2

Je n'ai jamais vraiment compris comment les listes d'arguments pour la surcharge des opérateurs sont déterminées de manière systématique, et je suis particulièrement confus par un problème que j'ai maintenant.Comment l'opérateur surcharge-t-il (en particulier le 'nouveau') travail?

Lorsque vous surchargez un opérateur unaire, il a un argument, ou zéro s'il s'agit d'un membre de classe. Lorsque vous surchargez un opérateur binaire, il a deux arguments, ou un si c'est un membre de la classe. Au moins, c'est comme ça que ça marcherait. J'ai un problème avec operator new (pas un membre de la classe) cependant.

Dans un codebase je travaille dans, comme dans d'autres endroits où je l'ai vu dans le passé (comme here par exemple) il y a une définir comme #define new new(__FILE__, __LINE__) et une fonction correspondante avec la signature void *new(size_t size, const char *file, unsigned line) ou quelque chose comme ça pour le débogage de mémoire . Je note que celui de mon projet est réellement différent du précédent. Cela me pose un problème, car pour une raison ou une autre, cela gâche un placement. J'ai regardé dans Le langage de programmation C++, et si cela explique cela, je l'ai manqué.

Est-ce que new est spécial à cet égard, c'est-à-dire a-t-il des signatures de débogage supplémentaires définies en langage spécifique? Cela ne semble pas être le cas car, comme je l'ai noté plus haut, j'ai vu des signatures légèrement différentes à différents endroits. Si c'est le cas, quels autres opérateurs ont des signatures non évidentes, et de quoi s'agit-il? Ces signatures variées sont-elles plutôt des extras spécifiques à l'implémentation? Si oui, existe-t-il des règles générales quant à ce que font la plupart des implémentations? Sinon, est-ce un problème d'arité comme je l'ai laissé entendre dans mon titre? Pouvez-vous juste ajouter autant d'arguments que vous voulez dans la signature et si vous appelez nouveau avec les arguments entre le mot-clé new lui-même et le nouveau type que vous voulez, vous pouvez simplement faire n'importe quoi? Ou suis-je encore plus confus, et il y a autre chose qui me manque?

Plus important encore dans le court terme (bien que j'aimerais vraiment comprendre ceci), que se passe-t-il sur mon emplacement new? La macro provoque une extension quelque chose comme new ("file.cpp", 100) (class_pointer) class_t. Est-ce que le problème est peut-être entre les deux groupes entre parenthèses, ou autre chose?

Répondre

0

L'arité d'un opérateur surchargé est tout ce que vous déclarez. Pour les opérateurs nommés après les symboles (+), si vous les définissez avec des arguments supplémentaires, ils ne seront invoqués que via un appel explicite. (opérateur + (a, b, c, d, e)). Pour l'opérateur new, vous devez lui donner au moins un argument, mais vous pouvez en donner autant que vous le souhaitez. La surcharge de l'opérateur détermine qui est appelé.

2

L'opérateur new est plus proche des fonctions car vous pouvez fournir autant de surcharges que vous le souhaitez et le compilateur choisira la version en fonction des règles de surcharge de fonction.

Alors, quand vous faites new ((T1)value1, (T2)value2) TYPE, qui va se routé vers:

operator new(size_t, T1, T2); 

Le problème avec votre macro est qu'il est en supposant que vous appelez la version simple de la nouvelle et qu'il peut utiliser le préprocesseur transformer cela en un appel au débogage nouveau. La macro est cassée lorsque vous devez appeler une autre version de nouveau.

Si vous devez appeler le placement nouveau (ou tout autre nouveau spécial), vous pouvez résoudre votre problème en désactivant cette macro:

#undef new