Указатель на вопрос Указатель

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

CNestedClass someClass( pInterface, ... );

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

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

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

РЕДАКТИРОВАТЬ: я должен уточнить - вложенный класс должен будет вызывать методы для объекта интерфейса, однако он не создает его (или изменяет объект, "на который" указывает), за это отвечает родительский класс.

5 ответов

Решение

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

Если это не ваша задача - убедиться, что объект остается в силе на протяжении всего жизненного цикла обоих классов.

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

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

Для умного указателя хорошим выбором будет 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 содержит только указатель RAW на объект pInterface, это означает, что объект Outer не владеет или не имеет никакого контроля над продолжительностью жизни объекта pInterface. Поэтому мы надеемся, что есть некоторая гарантия того, что объект pInterface будет жить так же долго, как и внешний объект; В этом случае нет никакой причины даже использовать указатель, вы могли бы просто использовать ссылку (при условии, что нет ситуации, когда pInterface будет иметь значение NULL).

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

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

и т.п.

Другие вопросы по тегам