Question

J'ai une classe avec un pointeur (non intelligent) sur un objet d'interface (appelons-le pInterface) et je construis une classe imbriquée qui a également besoin d'accéder à cette interface. Je vais contourner ce problème en passant le pointeur de l'interface dans le constructeur de la classe imbriquée comme suit:

CNestedClass someClass( pInterface, ... );

Cependant, je ne suis pas sûr du meilleur moyen de stocker ce pointeur dans la classe imbriquée. Je pourrais utiliser:

1) A scoped (or other smart) pointer (to the original object)
2) A pointer to a pointer 

Que suggéreriez-vous et pourquoi?

EDIT: Je dois préciser que la classe imbriquée aura besoin d'appeler des méthodes sur l'objet d'interface, mais elle ne le crée pas (ni ne modifie l'objet "pointé"), la classe parente en est responsable.

Était-ce utile?

La solution

L'utilisation d'un pointeur sur un pointeur est si l'une ou l'autre classe peut modifier la valeur du pointeur - par ex. en supprimant l'objet existant et en le remplaçant par un nouvel. Cela permet aux deux classes d’utiliser toujours le même objet en déréférencant le pointeur à pointeur.

Si ce n’est pas votre préoccupation, vous devez vous assurer que l’objet reste valide pendant toute la vie des deux classes.

  • Si la classe imbriquée a une vie plus courte, vous n'avez pas à vous inquiéter.
  • Si c'est la même chose, à condition que vous nettoyiez dans le bon ordre (par exemple, la classe imbriquée en premier, puis l'objet plus tard), vous n'avez pas à vous inquiéter
  • Si la classe imbriquée pouvait persister après la destruction du propriétaire, vous devez mettre en oeuvre un moyen de s'assurer que l'objet persiste également.

Si vous devez vous assurer de la durée de vie de l'objet, vous pouvez le faire via une sémantique de comptage de références, manuellement ou via une interface de pointeur intelligent.

Pour un pointeur intelligent, boost :: shared_ptr serait un bon choix. shared_ptr permet à la propriété d'un objet d'être partagée entre plusieurs pointeurs. Lorsque le dernier shared_ptr est hors de portée, l'objet est supprimé.

(notez que ce n'est pas le cas avec auto_ptr, où un objet appartient exclusivement).

Ce qu'il faut savoir;

  1. Lorsque vous utilisez boost :: shared_ptr, assurez-vous que la classe imbriquée a une copie du shared_ptr et non une référence / un pointeur.
  2. std :: auto_ptr se comporte très différemment, les objets sont la propriété exclusive et non partagés
  3. boost :: shared_ptr ne peut fonctionner qu'avec des objets tas, par exemple des pointeurs renvoyés par un appel à 'new'

Exemple:

typedef boost::shared_ptr<Interface> shared_interface;

class NestedClass
{
  shared_interface mInterface; // empty pointer
}

void NestedClass::setInterface(shared_interface& foo)
{
  mInterface= foo; // take a copy of foo.
}

void ParentClass::init( void )
{
  // mInterface is also declared as shared_interface
  mInterface = new Interface();
  mNestedClass->setInterface(mInterface);
}

Autres conseils

L'autre raison pour laquelle vous voudrez peut-être utiliser un pointeur sur un pointeur serait si le code externe pouvait changer la valeur d'origine du pointeur (par exemple, le faire pointer sur un nouvel objet ou le définir sur NULL après avoir relâché l'objet sur lequel il pointe). Cependant, à l’OMI, c’est une mauvaise pratique de changer un pointeur après l’avoir donné à quelqu'un d'autre.

Ainsi, si ni le code externe ni la classe imbriquée ne modifient le pointeur, stockez-le dans la classe imbriquée en tant que copie du pointeur d'origine en tant que variable membre (champ).

Indiquez l'adresse d'un pointeur sur votre interface (IMyInterface ** ppInterface) et remplissez-le s'il est implémenté par la classe.

La classe peut transtyper ce pointeur sur cette interface et y insérer le pointeur * ppInterface. Si la classe n'implémente pas cette interface, elle peut définir * ppInterface sur NULL.

En gros, vous partagez un pointeur sur le même objet entre deux objets différents. Si vous n'utilisez pas de pointeur intelligent, stockez simplement le pointeur sur l'objet partagé. Vous devez faire attention à la propriété de l'objet partagé, c'est-à-dire quel objet est responsable de la désallocation de l'objet partagé et d'avertir les autres qu'il est parti.

class Outer
{
    class Inner
    {
    };
};

Comme un objet d’Outer ne contient qu’un pointeur RAW sur un objet pInterface, cela signifie que l’objet Outer ne possède ni n’a aucun contrôle sur la durée de vie de l’objet pInterface. Nous espérons donc qu’il existe une garantie que l’objet pInterface vivra aussi longtemps que l’objet externe; Dans ce cas, il n'y a aucune raison d'utiliser un pointeur, vous pouvez simplement utiliser une référence (en supposant qu'il n'y ait pas de situation où pInterface serait NULL).

La manière dont Inner tient sa "référence" (et non la référence C ++) dépend et nous avons vraiment besoin de plus d’informations sur la relation entre les objets impliqués!

  • Quelle est la relation entre les objets intérieur et extérieur?
  • Quelle est la durée de vie d'un objet interne par rapport à l'objet externe dont il a hérité le pointeur pInterface?
  • Quelle est la garantie qu'un objet externe a une durée de vie plus courte qu'un objet pInterface.

etc.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top