2009-03-04 3 views
4

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

CNestedClass someClass(pInterface, ...); 

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

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

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

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

ответ

6

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

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

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

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

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

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

Вещи, которые следует учитывать;

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

:

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

Не могли бы вы более подробно остановиться? Если я использую интеллектуальный указатель, вероятно, было бы неплохо использовать общий указатель как в родительском, так и вложенном классах? – Konrad

+0

Я согласен, что единственная проблема заключается в том, что он должен оставаться в силе. Но другие методы доступны в зависимости от того, какой ребенок используется. (Пример: если продолжительность жизни ребенка будет меньше, чем родительский (затем передайте ссылку)). –

+0

+1 ссылка. Многие другие ответы касаются указателя на указатель, где ссылки гораздо лучше подходят. –

1

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

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

0

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

2

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

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

0
class Outer 
{ 
    class Inner 
    { 
    }; 
}; 

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

Как Внутренний имеет свою ссылку (а не ссылку на C++), и нам действительно нужна дополнительная информация о взаимосвязи между задействованными объектами!

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

т.д.

Смежные вопросы