boost :: shared_ptr и назначение производных классов - PullRequest
7 голосов
/ 27 февраля 2011

Предположим, DerivedClass является производным от BaseClass
Будет ли работать следующая операцияпроизводный и b указывает на основание (верно?)

Кроме того, теперь, если я вызову функцию через a, вызовет ли она производную реализацию?

Ответы [ 3 ]

13 голосов
/ 27 февраля 2011
...
a=b;

Вы переназначаетесь на a, и поэтому a и b теперь оба будут указывать на объект DerivedClass. Объект BaseClass будет уничтожен, поскольку его счетчик ссылок будет равен нулю в этой точке (в силу того, что a переназначается для указания на другой объект).

Поскольку a теперь указывает на объект DerivedClass, вызовы виртуальных функций (определенные в BaseClass и переопределяемые в DerivedClass) через a будут вызывать соответствующие функции-члены в DerivedClass.

Когда оба a и b выходят из области видимости, объект DerivedClass будет уничтожен.

Если вам нужен доступ к функциям, специфичным для производного класса, через a (например, не виртуальные функции в DerivedClass), вы можете использовать:

boost::dynamic_pointer_cast<DerivedClass>(a)->SomeFunctionOnlyInDerivedClass();

Конечно, это всего лишь краткий пример, демонстрирующий использование. В рабочем коде вы почти наверняка протестируете на успешное приведение к DerivedClass перед разыменованием указателя.

4 голосов
/ 27 февраля 2011

Предположим, DerivedClass является производным от BaseClass.Будет ли работать следующее?

Да.Так же, как нет ничего плохого в

boost::shared_ptr<BaseClass> pbase(new DerivedClass());

(Предполагая, что в обоих случаях BaseClass имеет виртуальный деструктор.) Интеллектуальный указатель разработан так, чтобы вести себя как простой указатель, насколько это возможно, и обеспечивать то же поведение, что иBaseClass* pbase = new DerivedClass();, плюс все эти качества управления жизненным циклом.

После этого вопроса я понимаю, что теперь a указывает на производное и b указывает на основание (верно?)

Нет, a и b оба указывают на экземпляр DerivedClass.Обмен, на который ссылается связанная статья, происходит на временном объекте внутри operator = .Когда этот временный объект выходит из области видимости, экземпляр BaseClass будет удален.

Кроме того, теперь, если я вызову функцию через a, будет ли она вызывать производную реализацию?

Да.Если вы посмотрите на реализацию оператора -> , все, что он делает, это возвращает указатель, на который должен быть вызван основной оператор -> :

T * operator-> () const // never throws
{
    BOOST_ASSERT(px != 0);
    return px;
}

так что поведение такое же, как у простого указателя.

3 голосов
/ 27 февраля 2011

Когда вы делаете a = b, вы говорите, что a указывает на объект, b также указывает на. Таким образом, все методы, которые вы вызываете, вы вызываете в части BaseClass объекта b, на который указывает.

Таким образом, если он содержит виртуальный метод, который перезаписывается в DerviedClass, называется перезаписанная версия.

...