C ++ удалить базу или указатель dynamic_cast? - PullRequest
0 голосов
/ 06 марта 2019

В ситуации, когда у нас есть объект производного класса, связанный с указателем базового класса bPtr, и указатель производного класса dPtr, указывающий на тот же объект через dynamic_cast<D*>, каков правильный способ очистки ресурсов?

class B {
public:
    B() { cout << "B_ctor" << endl; }
    virtual ~B() { cout << "B_destructor" << endl; }
    virtual void foo() { cout << "B_foo()" << endl; }
};

class D : public B {
public:
    D() { cout << "D_ctor" << endl; }
    ~D() { cout << "D_destructor" << endl; }
    void foo() { cout << "D_foo()" << endl; }
};   

int main() 
{ 
    B * bPtr = new D;
    D * dPtr = dynamic_cast<D*>(bPtr);
    bPtr->foo();
    dPtr->foo();
    //delete bPtr;
    delete dPtr;
}

Я решил удалить dPtr.Я также могу выбрать bPtr.Всякий раз, когда я делаю оба компилятора VS2015 высвечивает ошибку.Таким образом, мой вопрос, что является стандартным способом справиться с данной ситуацией?

Кроме того, всякий раз, когда я изменяю свой код на

D d;
B * bPtr = &d;
D * dPtr = dynamic_cast<D*>(bPtr);

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

Ответы [ 2 ]

4 голосов
/ 06 марта 2019

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

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

4 голосов
/ 06 марта 2019

D d определяет Автоматически назначенную переменную. Он автоматически удаляется, когда выходит из области видимости. Вам не нужно delete это, и так как оно не было выделено с new, вы не можете delete это.

Только delete что вы new и delete[] что вы new []. Если вы этого не сделали, не делайте этого. Если вы не указали переменную, обратитесь к документации по функции, которая предоставила переменную, чтобы узнать, как правильно ее использовать.

Дополнительные полезные сведения: Почему термины "автоматический" и "динамический" предпочтительнее терминов "стек" и "куча" в управлении памятью в C ++?

...