将子对象指针更改为父指针(没有内存泄漏)

时间:2015-12-05 06:01:05

标签: c++ pointers object scope dynamic-memory-allocation

在这个问题中:What do conditionals do to polymorphic objects in C++? (inclusion polymorphism)

我的情况是父指针指向由前面的条件语句确定的两个可能对象之一。以下是代码:(转载解决方案)

ClassParent *parentPointer; //Declare pointer to parent

if (condition) {
    ClassChild1* mychild = new mychild1(); //Initialize ClassChild1 object with pointer mychild
    parentPointer = mychild;//Parent pointer points to child1
}

if (!condition) {
    ClassChild2* mychild = new mychild2(); //Initialize ClassChild1 object with pointer mychild
    parentPointer = mychild;//Parent pointer points to child2  
}

cout << *parentPointer;

问题是,我的对象是用mychild指针创建的,但我希望这个指针是临时的。一旦parentPointer指向了对象,我想确保删除mychild指针(只是指针而不是对象)。

我不确定当它超出范围时是否会发生这种情况,因为指针是在'new'的上下文中声明的。

我是否需要手动删除mychild指针?如果是这样,如何在不导致parentPointer超出界限的情况下删除指针?

1 个答案:

答案 0 :(得分:0)

请考虑以下代码。

#include <iostream>

using namespace std;

class A { };

class B: public A { };

class C: public A { };

ostream &operator<<(ostream &os, const A &){ return os << 'A'; }

ostream &operator<<(ostream &os, const B &){ return os << 'B'; }

ostream &operator<<(ostream &os, const C &){ return os << 'C'; }

int main(){
    A *a1=new B;
    A *a2=new C;
    cout << *a1 << *a2 << '\n';
}

它将打印AA,而不是BC。即使指针a1a2确实指向BC类型的对象,它们仍然是“指向A的指针”类型,当您将*运算符应用于它们时,表达式将具有A类型。

要真正运用对象多态,你应该使用虚函数。

class A {
    public:
        virtual char getName() const { return 'A'; }
};

class B {
    public:
        char getName() const { return 'B'; }
};

class C {
    public:
        char getName() const { return 'C'; }
};

ostream &operator<<(ostream &os, const A &a_like){
    return os << a_like.getName();
}

// remove ostream &operator<<(ostream &os, const B &)

// remove ostream &operator<<(ostream &os, const C &)

编辑:最后,既然你提到没有内存泄漏,并且在指向基类型的指针集合中存储指向派生类型对象的指针,那么你可能想要制作你的析构函数virtual也是如此。通过这样做,在销毁指针(通过delete运算符)或对基类型的引用时释放的资源将对派生类型的实际底层对象执行必要的清理操作。

也不要忘记,如果你有类似vector<SomeClass *>的东西,指针元素在销毁矢量容器时不会单独delete d。你应该在向量被销毁之前明确地delete每个元素,用智能指针(例如unique_ptrshared_ptr)包围你的指针,或者为你的多态对象创建你自己的RAII包络,或许意识到移动操作。