Opérateur public nouveau, opérateur privé supprimer: obtenir C2248 «ne peut accéder au membre privé» lors de l'utilisation d'un nouveau
-
10-07-2019 - |
Question
Une classe a surchargé les opérateurs new
et delete
. new
est public, delete
est privé.
Lors de la construction d'une instance de cette classe, j'obtiens le message d'erreur suivant:
pFoo = new Foo(bar)
example.cpp (1): erreur C2248: 'Foo: opérateur delete': impossible d'accéder au membre privé déclaré dans la classe 'Foo'
Mais il n'y a pas d'appel à supprimer
ici, que se passe-t-il dans l'esprit tordu du compilateur? :)
- Quelle est la raison de l'erreur?
- Est-il possible de résoudre le problème sans recourir à une fonction membre
CreateInstance
?
La solution
Lorsque vous faites new Foo ()
, il se produit deux choses: le premier opérateur new
est appelé pour allouer de la mémoire, puis un constructeur pour Foo
est appelé. Si vous ne pouvez pas accéder à la mémoire déjà allouée par ce constructeur, le runtime C ++ s'en chargera en la passant à l'opérateur approprié delete
. C'est pourquoi vous devez toujours implémenter un opérateur delete
correspondant pour chaque opérateur nouveau
que vous écrivez et c'est pourquoi il doit être accessible.
Pour sortir, vous pouvez les rendre tous les deux privés et appeler le opérateur new
à partir d'une fonction membre publique (comme create ()
).
Autres conseils
Vérifiez ceci . Dans l'un des paragraphes inférieurs, il est indiqué que new nécessite la suppression pour être accessible. En gros, cela signifie que vous ne pouvez créer des objets sur le tas que si vous pouvez également les supprimer à nouveau.
Selon les normes C ++, lorsque vous avez une classe avec une allocation de mémoire dynamique et qu'une exception est levée dans le constructeur, vous devez libérer la mémoire pour éviter les fuites de mémoire.
Ici, vous avez défini votre nouvel opérateur comme public, mais la suppression est privée.
Donc, le compilateur vous dit que cela me donne accès à supprimer opérateur afin que je puisse empêchez la fuite de mémoire si une exception est levée dans le constructeur.
Si vous ne définissez pas votre opérateur de suppression, le compilateur génère également une erreur et vous oblige à la définir.
-
"1.Quelle est la raison de l'erreur?"
La réponse de sbi est bonne.
-
"2. Est-il possible de résoudre le problème sans recourir à une fonction membre CreateInstance?"
Oui. Créer un destructeur privé.
L'opérateur appelant new on class utilisera également delete class si le constructeur de la classe lève une exception.
Si votre bibliothèque n'utilise pas d'exceptions, vous pouvez désactiver les exceptions du compilateur "-fno-exceptions", alors l'erreur n'apparaîtra plus. (Dans Visual studio se trouve sous "C / C ++", "Génération de code", "Activer les exceptions C ++" > "Non (-fno-exceptions)")