2013-12-11 7 views
3

Допустим, у меня есть базовый класс и производный класс:Можно ли инициализировать auto_ptr с указателем на производный класс?

class Base 
{ 
    public: 
     virtual ~Base() {} 
     virtual void DoSomething() = 0; 
}; 


class Child : public Base 
{ 
    public: 
     virtual void DoSomething() 
     { 
      // Do Something 
     } 
}; 

Безопасно ли инициализировать зЬй :: auto_ptr типа базового класса с указателем на экземпляр производного класса? И.Е. будет объект, созданный, как это:

std::auto_ptr<Base> myObject(new Derived()); 

правильно вызывать деструктор производного класса вместо базового класса без утечки памяти?

+0

Этот вопрос не зависит от auto_ptr, не так ли? Он относится ко всем указателям. Если бы вы не могли этого сделать, у вас не было бы полиморфизма на C++, что было бы грустно. –

+0

@PeterSchneider Этот вопрос относится только к auto_ptr. В основном я хотел убедиться, что его [реализация не срезала объект, переданный в] (http://stackoverflow.com/questions/274626/what-is-the-slicing-problem-in-c), но я также хотел узнать, что произошло, как о виртуальных деструкторах. – TwentyMiles

ответ

5

Несмотря на то, что вы не должны использовать std::auto_ptr с момента прибытия C++ 11;

Да, это безопасно до тех пор, как ваша база имеет виртуальный деструктор.

Без виртуального деструктора на базе (например, Steve Jessop, указанный ниже) вы получите неопределенное поведение, поскольку деструктор класса вывода будет неизвестен во время уничтожения и, следовательно, не будет выполнен. Это опасная проблема, поскольку во многих случаях она остается незамеченной. Например, если вы управляете каким-то ресурсом в классе с одним наследованием, который должен был быть освобожден в деструкторе, утечка произошла бы молча.

+1

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

+0

Спасибо, добавил к моему ответу. –

0

Пока ваш класс Basestd::auto_ptr<Base> спараметрирован с имеет virtual деструктор вы можете инициализировать std::auto_ptr<Base> с классами, полученных из Base и они будут надлежащим образом уничтожены, если std::auto_ptr<Base> деструктора конкретизируются, когда определение Base видно.