问题
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 delete
d 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