Changing child object pointer to parent pointer (without memory leak)

筅森魡賤 提交于 2019-12-23 05:15:09

问题


In this question: What do conditionals do to polymorphic objects in C++? (inclusion polymorphism)

I have a situation where a parent pointer is pointing at one of two possible objects determined by the preceding conditional statement. Here is the code: (Reposted with solution)

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;

The problem is, my object is created with mychild pointer but I want this pointer to be temporary. Once the object is pointed to by the parentPointer, I want to make sure mychild pointer is deleted (just the pointer not the object).

I'm not sure if this will happen when it goes out of scope, because the pointer was declared within the context of 'new'.

Do I need to delete the mychild pointer manually? If so, how do I delete the pointer without causing the parentPointer to go out of bounds?


回答1:


Consider the following code.

#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';
}

It will print AA, not BC. Even though the pointers a1 and a2 really point to objects of types B and C, they're still of type “pointer to A”, and when you apply the * operator to them, the expression will have the type A.

To really exercise object polymorphism, you should use virtual functions.

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 &)

EDIT: Lastly, since you mentioned not having memory leaks and also storing pointers to objects of derived types in a collection of pointers to the base type, you'll probably want to make your destructors virtual as well. By doing so, the resources freed at the destruction of the pointer (through the delete operator) or reference to the base type will perform the necessary clean-up actions on the actual underlying object of the derived type.

Don't forget, also, that if you have something like vector<SomeClass *>, the pointer elements will not be individually deleted at the time of destruction of the vector container. You should either explicitly delete each element before the vector gets destroyed, envelop your pointers with a smart pointer (such as unique_ptr or shared_ptr), or create your own RAII envelope to your polymorphic objects, perhaps aware of with move operations.



来源:https://stackoverflow.com/questions/34101844/changing-child-object-pointer-to-parent-pointer-without-memory-leak

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!