Вопрос

У меня есть класс с (не интеллектуальным) указателем на объект интерфейса (назовем его pInterface), и я создаю вложенный класс, которому также нужен доступ к этому интерфейсу.Я собираюсь обойти это, передав указатель на интерфейс в конструктор вложенного класса следующим образом:

CNestedClass someClass( pInterface, ... );

Однако я не уверен в наилучшем способе хранения этого указателя во вложенном классе.Я мог бы использовать:

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

Что бы вы, ребята, предложили и почему?

Редактировать:Я должен уточнить - вложенному классу потребуется вызывать методы для объекта интерфейса, однако он не создает его (или не изменяет объект, на который "указывает"), за это отвечает родительский класс.

Это было полезно?

Решение

Использовать указатель на указатель можно, если любой из классов может изменить значение указателя - напримерудалив существующий объект и заменив его новым.Это позволяет обоим классам по-прежнему использовать один и тот же объект путем разыменования указателя на указатель.

Если нет, то ваша забота заключается в том, чтобы объект оставался действительным на протяжении всего срока службы обоих классов.

  • Если вложенный класс живет короче, вам действительно не о чем беспокоиться.
  • Если это то же самое, при условии, что вы производите очистку в правильном порядке (напримерсначала вложенный класс, объект позже) с другой стороны, вам не нужно беспокоиться
  • Если вложенный класс может сохраниться после уничтожения владельца, то вы должны реализовать способ гарантировать, что объект также сохранится.

Если вам нужно обеспечить время жизни объекта, это можно сделать с помощью семантики подсчета ссылок, либо вручную, либо через интерфейс интеллектуального указателя.

Для умного указателя хорошим выбором был бы boost::shared_ptr.shared_ptr позволяет передавать право собственности на объект нескольким указателям.Когда последний shared_ptr выходит за пределы области видимости, объект удаляется.

(обратите внимание, что это не относится к auto_ptr, где объект принадлежит исключительно вам).

Вещи, о которых нужно знать;

  1. При использовании boost::shared_ptr убедитесь, что вложенный класс имеет Копировать из shared_ptr, а не из ссылки / указателя.
  2. std:: auto_ptr ведет себя совершенно по-другому, объекты принадлежат исключительно, а не совместно используются
  3. boost::shared_ptr может работать только с объектами кучи, например, указателями, возвращаемыми при вызове 'new'

Пример:

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);
}

Другие советы

Другая причина, по которой вы можете захотеть использовать указатель на указатель, заключается в том, что код внешний может изменить исходное значение указателя (например, сделать его указателем на новый объект или установить его в NULL). после освобождения объекта он указывает на). Тем не менее, IMO это очень плохая практика, чтобы изменить указатель после передачи его кому-то еще.

Итак, если ни внешний код, ни вложенный класс не изменяют указатель, просто сохраните его во вложенном классе как копию исходного указателя как переменную-член (поле).

Передайте адрес указателя на ваш интерфейс (IMyInterface ** ppInterface) и заполните указатель, если он реализован классом.

Класс может привести свой указатель this к этому интерфейсу и заполнить указатель * ppInterface. Если класс не реализует этот интерфейс, он может установить * ppInterface в NULL.

По сути, вы делите указатель на один и тот же объект между двумя разными объектами. Если вы не используете умные указатели, просто сохраните указатель на общий объект. Вы должны быть осторожны с владельцем общего объекта, т. Е. Какой объект отвечает за освобождение общего объекта и уведомление других о его исчезновении.

class Outer
{
    class Inner
    {
    };
};

Поскольку объект Outer содержит только НЕОБРАБОТАННЫЙ указатель на объект pInterface, это означает, что Внешний объект не является владельцем объекта pInterface и не имеет никакого контроля над сроком службы объекта pInterface.Поэтому мы надеемся, что есть некоторая гарантия того, что объект pInterface будет жить так же долго, как и внешний объект;В этом случае нет причин даже использовать указатель, вы могли бы просто использовать ссылку (предполагая, что нет ситуации, когда pInterface был бы нулевым).

То, как Inner хранит свою "ссылку" (не ссылку на C ++), зависит, и на самом деле нам нужно больше информации о взаимосвязи между задействованными объектами!

  • Какова взаимосвязь между Внутренними и Внешними объектами?
  • Каков срок службы Внутреннего объекта по отношению к Внешнему объекту, от которого он унаследовал указатель pInterface?
  • Какова гарантия того, что срок службы внешнего объекта короче, чем у объекта pInterface?

и т.д.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top