Salut, pouvez-vous clarifier la question? On dirait qu'il y a une faute de frappe quelque part.
Dima Malenko
17
La question est formulée correctement, voir les réponses ci-dessous. La méthode d'allocation dynamique de mémoire consiste à utiliser l' newopérateur. Cet opérateur peut être surchargé. Pour faire la distinction entre l'opérateur par défaut et une version surchargée, la valeur par défaut est appelée «nouvel opérateur» et la version surchargée est appelée «opérateur nouveau».
Thomas Matthews
2
Comment faire ça. Je suis nouveau et inconscient.
Sandeep
Réponses:
127
J'essaie généralement de formuler les choses différemment pour différencier un peu mieux les deux, mais c'est une bonne question dans tous les cas.
Operator new est une fonction qui alloue de la mémoire brute - du moins conceptuellement, ce n'est pas très différent de malloc(). Bien que ce soit assez inhabituel à moins que vous n'écriviez quelque chose comme votre propre conteneur, vous pouvez appeler l'opérateur new directement, comme:
char*x =static_cast<char*>(operatornew(100));
Il est également possible de surcharger l'opérateur new soit globalement, soit pour une classe spécifique. IIRC, la signature est:
void*operatornew(size_t);
Bien sûr, si vous surchargez un opérateur new (global ou pour une classe), vous voudrez / devrez également surcharger l'opérateur correspondant delete. Pour ce que ça vaut, il y a aussi un opérateur séparé new [] qui est utilisé pour allouer de la mémoire aux tableaux - mais il vaut certainement mieux ignorer complètement tout ce désordre.
Le nouvel opérateur est ce que vous utilisez normalement pour créer un objet à partir du magasin gratuit:
my_class *x =new my_class(0);
La différence entre les deux est que l'opérateur new alloue simplement de la mémoire brute, rien d'autre. L'opérateur new commence par utiliser l'opérateur new pour allouer de la mémoire, mais il appelle ensuite le constructeur pour le bon type d'objet, le résultat est donc un véritable objet vivant créé dans cette mémoire. Si cet objet contient d'autres objets (incorporés ou en tant que classes de base), ces constructeurs sont également appelés.
+1, quant à une formulation différente, la norme utilise une nouvelle expression tout autour, et seulement une fois qu'elle utilise un nouvel opérateur pour se référer au lieu de l'appel. J'ai tendance à faire la même chose: opérateur nouveau pour l' allocateur et nouvelle expression pour l'utilisation.
David Rodríguez - dribeas
3
Une nouvelle expression est la phrase entière qui commence par nouveau. Alors, comment appelez-vous juste la «nouvelle» partie de celui-ci? S'il est faux d'appeler cela l'opérateur new, alors nous ne devrions pas appeler "sizeof" l'opérateur sizeof, ou & l'opérateur address-of (quand il se comporte comme tel).
Kaz
1
Suite à la remarque de Kaz, la question devrait peut-être être reformulée comme suit: Quelle est la différence entre le nouvel opérateur et le nouvel opérateur? :)
CS
2
"operator new" vs "new keyword"
user997112
2
@antred: Vous sortiriez ça avec quelque chose comme operator delete(x);.
Jerry Coffin
35
"opérateur nouveau"
classFoo{public:void*operatornew(size_t);}
"nouvel opérateur":
Foo* foo =newFoo();
Dans cet exemple, les new Foo()appelsFoo::operator new()
En d'autres termes, "nouvel opérateur" appelle " operator new()" tout comme l'opérateur + appelleoperator +()
newn'est pas un opérateur en C ++. sizeof, par exemple, est un opérateur, mais newet deletene le sont pas. newet deletesont des mots-clés et les constructions syntaxiques que ces mots-clés forment sont appelées new-expression et delete-expression .
AnT
2
Euh, si quelque chose sizeofest la construction syntaxique, et newet deletesont tous deux des opérateurs valides, légaux et surchargeables. De tout ce que j'ai jamais vu, newet deletesont les deux opérateurs. Voir [cplusplus.com] [ cplusplus.com/doc/tutorial/classes2/]
Austin Hyde
7
Incorrect. La terminologie officielle C ++ est la terminologie définie par la spécification du langage, et non par certains sites Web. Dans la spécification du langage, il n'y a pas de "nouvel opérateur", mais il y a un terme comme " operator newfonction". Encore une fois, sizeofest explicitement appelé «opérateur», alors que newet nedelete sont jamais appelés opérateurs.
AnT
6
AndreyT: Incorrect. Le standard C ++ appelle «new» un opérateur, voir 13.5 / 1.
3
@AndreyT: Je pensais comme vous, que l' opérateur new était l' allocateur et la nouvelle expression des utilisations. J'ai revu et vérifié qu'au §5.3.4 / 3 la norme actuelle utilise le terme nouvel opérateur . Plus tard dans le §5.3.4 / 8, il nomme les fonctions d'allocateur comme opérateur nouveau et opérateur nouveau []
David Rodríguez - dribeas
22
Voici la citation du livre More Effective C ++ de Scott Meyers:
Le nouvel opérateur appelle une fonction pour effectuer l'allocation de mémoire requise et vous pouvez réécrire ou surcharger cette fonction pour modifier son comportement. Le nom de la fonction que le nouvel opérateur appelle pour allouer de la mémoire est operator new.
Le terme est évidemment inventé par l'auteur du livre (ou peut-être emprunté à une source obsolète). Dans la nomenclature formelle C ++, il n'y a pas de terme tel que "nouvel opérateur".
AnT
2
@AndreyT: J'ai fait une recherche dans le C ++ 11 pour "nouvel opérateur" et je l'ai trouvé référencé à quatre endroits. Plus précisément, deux références au «nouvel opérateur de placement»
Mooing Duck
11
Il n'y a aucune différence entre «nouvel opérateur» et «nouvel opérateur». Les deux font référence à la même chose: la fonction surchargeable / remplaçable operator newqui effectue généralement une allocation de mémoire brute pour les objets créés par de nouvelles expressions .
Notez également qu'aucun terme n'est présent dans la spécification de la langue (qui est la source de définition de la terminologie officielle).
Lorsque vous utilisez newdans votre programme pour créer un objet, il est appelé new-expression . La nouvelle expression se compose de mots new- clés et de parties syntaxiques supplémentaires définies par la grammaire. Aucune partie de la syntaxe de cette expression n'est jamais appelée "opérateur".
La fonction d'allocation de mémoire brute operator newest officiellement appelée simplement « operator newfonction». Notez que les mots operatoret newdans cette séquence ne sont que deux mots-clés de langage C ++ distincts. Ils ne forment pas un terme anglais "operator new". Nulle part dans la spécification de la langue, vous ne trouverez des références à «opérateur nouveau» en tant que terme anglais. À chaque fois, il ne s'agit que d'une combinaison de deux mots-clés indépendants qui produisent une syntaxe de déclaration pour une fonction d'allocation de mémoire.
Encore une fois, en résumé: formellement en C ++, il n'y a pas de termes en anglais tels que «opérateur nouveau» ou «nouvel opérateur». La première séquence est présente dans la spécification de la langue comme une simple combinaison de mots-clés, et non comme un terme anglais. Ce dernier n'est pas du tout présent.
Vous semblez perdu dans une masturbation mentale pédante. La norme est vague par endroits, et c'est l'un d'entre eux. Il est tout aussi logique de "discuter du nouvel opérateur" que de "discuter de l'opérateur plus" ou de "discuter de l'opérateur +".
7
Lorsque vous créez un nouvel objet, la mémoire est allouée à l' aide de l' opérateur new, puis le constructeur est appelé pour initialiser la mémoire. Le nouvel opérateur effectue à la fois l'allocation et l'initialisation, alors qu'en tant qu'opérateur nouveau, seul l'attribution est effectuée.
La question du PO n'est pas formulée correctement. Il est préférable de passer en phase comme 'Différence entre' opérateur nouveau 'et' nouvelle expression '?' Remarque «opérateur nouveau» fait souvent également référence à «nouvelle fonction opérateur».
Et il y a beaucoup de bonnes réponses, ci-dessous est la mienne:
1> 'new expression' appelez 'operator new' pour allouer de la mémoire brute, puis appelez constructeur
apple * p =new apple();//new expression
2> 'opérateur nouveau' n'alloue que de la mémoire brute, pas beaucoup de différence que malloc
void* mem =operatornew(sizeof(apple));//just like calling malloc()
apple* p2 =new(mem) apple(1);//call construct here using placement new.
Le nouvel opérateur : C ++ prend en charge l'allocation dynamique d'objets à l'aide du nouvel opérateur. Le nouvel opérateur alloue de la mémoire pour les objets d'un pool appelé le magasin gratuit. Le nouvel opérateur appelle l'opérateur de fonction spéciale nouveau.
opérateur nouveau : Si la demande porte sur zéro octet de stockage, l'opérateur new renvoie un pointeur vers un objet distinct (c'est-à-dire que les appels répétés à l'opérateur new renvoient des pointeurs différents). S'il n'y a pas assez de mémoire pour la demande d'allocation, l'opérateur new renvoie NULL ou lève une exception. Le premier argument de l'opérateur new doit être de type size_t (un type défini dans STDDEF.H), et le type de retour est toujours void *.
Légère précision: l'opérateur de non-placement nouveau doit toujours se jeter sur l'échec d'allocation (selon la norme); et les formulaires de placement, tels que ::new(std::nothrow), peuvent faire l'un ou l'autre (cet exemple spécifique renvoie un pointeur nul).
1
new est à la fois un opérateur et un mot-clé.
voir [1] dans 2.13 && dans 2.12.
new fait deux choses: T * t = new T (arg);
1) allouer de la mémoire pour l'objet: void * ptr = opérateur new (sizeof (T));
// L' opérateur new est une fonction (tout comme malloc en c), pas un opérateur (voir [1] en 3.7.4). Mais le point 7 [2] dit que c'est aussi un opérateur. À mon avis, la différence entre opérateur et fonction est petite, et vous pouvez le voir lorsque vous vous rappelez que la surcharge de l'opérateur est implémentée par des fonctions.
// nous pouvons surcharger cet opérateur / fonction (opérateur nouveau) en faisant ce que nous voulons juste ici.
2) initialiser l'objet dans la mémoire allouée: appeler T :: T (arg) sur ptr
// seul le compilateur peut le faire. Ni moi ni vous ne le pouvez.
// également le compilateur invoquera les constructeurs des objets membres et le constructeur de la classe de base si T les a. Et cette invocation est récursive. Seul le compilateur peut le faire.
Ainsi, l'opérateur new fait partie des missions de new, et ce n'est que dans cette partie que nous pouvons faire quelque chose.
new
opérateur. Cet opérateur peut être surchargé. Pour faire la distinction entre l'opérateur par défaut et une version surchargée, la valeur par défaut est appelée «nouvel opérateur» et la version surchargée est appelée «opérateur nouveau».Réponses:
J'essaie généralement de formuler les choses différemment pour différencier un peu mieux les deux, mais c'est une bonne question dans tous les cas.
Operator new est une fonction qui alloue de la mémoire brute - du moins conceptuellement, ce n'est pas très différent de
malloc()
. Bien que ce soit assez inhabituel à moins que vous n'écriviez quelque chose comme votre propre conteneur, vous pouvez appeler l'opérateur new directement, comme:Il est également possible de surcharger l'opérateur new soit globalement, soit pour une classe spécifique. IIRC, la signature est:
Bien sûr, si vous surchargez un opérateur new (global ou pour une classe), vous voudrez / devrez également surcharger l'opérateur correspondant delete. Pour ce que ça vaut, il y a aussi un opérateur séparé new [] qui est utilisé pour allouer de la mémoire aux tableaux - mais il vaut certainement mieux ignorer complètement tout ce désordre.
Le nouvel opérateur est ce que vous utilisez normalement pour créer un objet à partir du magasin gratuit:
La différence entre les deux est que l'opérateur new alloue simplement de la mémoire brute, rien d'autre. L'opérateur new commence par utiliser l'opérateur new pour allouer de la mémoire, mais il appelle ensuite le constructeur pour le bon type d'objet, le résultat est donc un véritable objet vivant créé dans cette mémoire. Si cet objet contient d'autres objets (incorporés ou en tant que classes de base), ces constructeurs sont également appelés.
la source
operator delete(x);
."opérateur nouveau"
"nouvel opérateur":
Dans cet exemple, les
new Foo()
appelsFoo::operator new()
En d'autres termes, "nouvel opérateur" appelle "
operator new()
" tout comme l'opérateur + appelleoperator +()
la source
new
n'est pas un opérateur en C ++.sizeof
, par exemple, est un opérateur, maisnew
etdelete
ne le sont pas.new
etdelete
sont des mots-clés et les constructions syntaxiques que ces mots-clés forment sont appelées new-expression et delete-expression .sizeof
est la construction syntaxique, etnew
etdelete
sont tous deux des opérateurs valides, légaux et surchargeables. De tout ce que j'ai jamais vu,new
etdelete
sont les deux opérateurs. Voir [cplusplus.com] [ cplusplus.com/doc/tutorial/classes2/]operator new
fonction". Encore une fois,sizeof
est explicitement appelé «opérateur», alors quenew
et nedelete
sont jamais appelés opérateurs.Voici la citation du livre More Effective C ++ de Scott Meyers:
la source
Il n'y a aucune différence entre «nouvel opérateur» et «nouvel opérateur». Les deux font référence à la même chose: la fonction surchargeable / remplaçable
operator new
qui effectue généralement une allocation de mémoire brute pour les objets créés par de nouvelles expressions .Notez également qu'aucun terme n'est présent dans la spécification de la langue (qui est la source de définition de la terminologie officielle).
Lorsque vous utilisez
new
dans votre programme pour créer un objet, il est appelé new-expression . La nouvelle expression se compose de motsnew
- clés et de parties syntaxiques supplémentaires définies par la grammaire. Aucune partie de la syntaxe de cette expression n'est jamais appelée "opérateur".La fonction d'allocation de mémoire brute
operator new
est officiellement appelée simplement «operator new
fonction». Notez que les motsoperator
etnew
dans cette séquence ne sont que deux mots-clés de langage C ++ distincts. Ils ne forment pas un terme anglais "operator new". Nulle part dans la spécification de la langue, vous ne trouverez des références à «opérateur nouveau» en tant que terme anglais. À chaque fois, il ne s'agit que d'une combinaison de deux mots-clés indépendants qui produisent une syntaxe de déclaration pour une fonction d'allocation de mémoire.Encore une fois, en résumé: formellement en C ++, il n'y a pas de termes en anglais tels que «opérateur nouveau» ou «nouvel opérateur». La première séquence est présente dans la spécification de la langue comme une simple combinaison de mots-clés, et non comme un terme anglais. Ce dernier n'est pas du tout présent.
la source
Lorsque vous créez un nouvel objet, la mémoire est allouée à l' aide de l' opérateur new, puis le constructeur est appelé pour initialiser la mémoire. Le nouvel opérateur effectue à la fois l'allocation et l'initialisation, alors qu'en tant qu'opérateur nouveau, seul l'attribution est effectuée.
la source
La question du PO n'est pas formulée correctement. Il est préférable de passer en phase comme 'Différence entre' opérateur nouveau 'et' nouvelle expression '?' Remarque «opérateur nouveau» fait souvent également référence à «nouvelle fonction opérateur».
Et il y a beaucoup de bonnes réponses, ci-dessous est la mienne:
1> 'new expression' appelez 'operator new' pour allouer de la mémoire brute, puis appelez constructeur
2> 'opérateur nouveau' n'alloue que de la mémoire brute, pas beaucoup de différence que malloc
la source
Le nouvel opérateur : C ++ prend en charge l'allocation dynamique d'objets à l'aide du nouvel opérateur. Le nouvel opérateur alloue de la mémoire pour les objets d'un pool appelé le magasin gratuit. Le nouvel opérateur appelle l'opérateur de fonction spéciale nouveau.
opérateur nouveau : Si la demande porte sur zéro octet de stockage, l'opérateur new renvoie un pointeur vers un objet distinct (c'est-à-dire que les appels répétés à l'opérateur new renvoient des pointeurs différents). S'il n'y a pas assez de mémoire pour la demande d'allocation, l'opérateur new renvoie NULL ou lève une exception. Le premier argument de l'opérateur new doit être de type size_t (un type défini dans STDDEF.H), et le type de retour est toujours void *.
Voici les liens MSDN pour plus de détails:
La nouvelle fonction de l'opérateur
Le nouvel opérateur
la source
::new(std::nothrow)
, peuvent faire l'un ou l'autre (cet exemple spécifique renvoie un pointeur nul).new est à la fois un opérateur et un mot-clé.
voir [1] dans 2.13 && dans 2.12.
new fait deux choses: T * t = new T (arg);
1) allouer de la mémoire pour l'objet: void * ptr = opérateur new (sizeof (T));
// L' opérateur new est une fonction (tout comme malloc en c), pas un opérateur (voir [1] en 3.7.4). Mais le point 7 [2] dit que c'est aussi un opérateur. À mon avis, la différence entre opérateur et fonction est petite, et vous pouvez le voir lorsque vous vous rappelez que la surcharge de l'opérateur est implémentée par des fonctions.
// nous pouvons surcharger cet opérateur / fonction (opérateur nouveau) en faisant ce que nous voulons juste ici.
2) initialiser l'objet dans la mémoire allouée: appeler T :: T (arg) sur ptr
// seul le compilateur peut le faire. Ni moi ni vous ne le pouvez.
// également le compilateur invoquera les constructeurs des objets membres et le constructeur de la classe de base si T les a. Et cette invocation est récursive. Seul le compilateur peut le faire.
Ainsi, l'opérateur new fait partie des missions de new, et ce n'est que dans cette partie que nous pouvons faire quelque chose.
[1]: ISO / CEI, N3690. http://ww.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf
[2]: Meyers, Scott. C ++ efficace, 3e.
la source