2010-03-26 5 views
1

Pour une classe sans constructeur par défaut, operator new et placement new peuvent être utilisés pour déclarer un tableau de cette classe.opérateur new pour tableau de classe sans constructeur par défaut

Quand je lis le code plus efficace C++, j'ai trouvé le code comme ci-dessous (je l'ai modifié une partie) .....

Ma question est, pourquoi [] après que l'opérateur nouvelle est nécessaire?

Je l'ai testé sans ça, ça marche toujours. Quelqu'un peut-il expliquer cela?

class A { 
    public: 
    int i; 

    A(int i):i(i) {} 
}; 

int main() 
{ 
     void *rawMemory = operator new[] (10 * sizeof(A)); // Why [] needed here? 
     A *p = static_cast<A*>(rawMemory); 

     for(int i = 0 ; i < 10 ; i++) { 

      new(&p[i])A(i); 

     } 

     for(int i = 0 ; i < 10 ; i++) { 

      cout<<p[i].i<<endl; 

     } 

     for(int i = 0 ; i < 10 ; i++) { 

      p[i].~A(); 

     } 

    return 0; 
} 
+3

Ceci est une sorte de duplicata de http://stackoverflow.com/questions/2498183/qui-pour-utiliser-opérateur-nouveau-un-operateur-nouveau-pour-allouer-unbloc-d'essai- moi, mais cette question n'a pas vraiment généré de réponses, juste un tas de variantes de "l'opérateur global nouveau est une fonctionnalité stupide qui ne devrait pas être en C++ en premier lieu, et quiconque l'appelle sent le pantalon". Celui-ci, en revanche, a quelques réponses, essentiellement "cela ne fait aucune différence, il suffit d'utiliser la bonne version de' operator delete' ": http: // stackoverflow.com/questions/2499895/whats-the-but-of-having-a-separate-operator-new –

+0

Si vous vous souveniez de 'supprimer []' votre mémoire, vous auriez vu la seule différence qu'il fait. ':)' – sbi

Répondre

2

Je suis surpris que Effective C++ vous conseille d'utiliser quelque chose d'aussi hackish qu'un void*.

new[] fait une chose très spécifique: il alloue un tableau de taille dynamique. Un tableau alloué avec lui doit être passé à delete[]. delete[] puis lit un nombre masqué pour trouver le nombre d'éléments dans le tableau et détruit les objets comme vous l'avez fait avec p[i].~A();.

Cependant, cette utilisation est incompatible avec cela. Le tableau est statiquement dimensionné, et il n'y a aucun moyen d'obtenir ce nombre masqué ou la destruction de taille dynamique sans utiliser correctement new[] (no operator), nécessitant à son tour un constructeur par défaut. Une véritable faiblesse de C++.

Si vous avez appelé delete[] à la fin de main comme d'autres l'ont suggéré, votre code pourrait tomber en panne. Au lieu de cela, vous devez utiliser operator delete[], qui ressemble à une faute de frappe et est juste un accident qui attend de se produire.

Utilisez non-tableau operator new et operator delete et amples commentaires si vous devez utiliser cette astuce. Mais je ne considérerais pas ce C++ particulièrement efficace.

2

Ce n'est pas nécessaire. La seule différence entre operator new et operator new [] est que le premier est appelé par l'utilisation du mot-clé new et l'autre par le mot-clé new []. Les deux allouent de la mémoire brute. Assurez-vous que lorsque vous libérez enfin de la mémoire (votre code fuit juste ici) que vous appelez la suppression ou la suppression [] qui correspond à nouveau ou nouveau [].

1

Ce n'est pas strictement nécessaire dans ce cas. Ils alloueront tous deux la même quantité de mémoire, mais l'un d'entre eux nécessitera delete et un autre aura besoin de delete[] à la fin. L'utilisation de new[] rend votre intention un peu plus claire, c'est pourquoi il est utilisé ici.

0

Ce n'est pas vraiment nécessaire - cela vous donne juste une chance d'allouer de la mémoire pour les baies séparément de la mémoire pour les objets individuels, si vous choisissez de le faire.

Questions connexes