I have a simple program
$ cat a.cpp
#include <iostream>
class MyClass {
public:
virtual void check() {
std::cout << "Inside MyClass\n";
}
};
class MyClass2: public MyClass {
public:
int* a;
virtual void check() {
std::cout << "Inside MyClass2\n";
}
};
int main() {
MyClass *w, *v;
w = new MyClass2[2];
v = new MyClass2;
std::cout << "Calling w[0].check\n"; w[0].check();
std::cout <开发者_C百科;< "Calling v->check\n"; v->check();
std::cout << "Calling w[1].check\n"; w[1].check();
}
$ g++ a.cpp
$ ./a.out
Calling w[0].check
Inside MyClass2
Calling v->check
Inside MyClass2
Calling w[1].check
Segmentation fault
I thought it is possible to use new to allocate derived class objects. Also, v->check() seems to work fine.
w = new MyClass2[2];
This creates an array of two MyClass2
objects. It is of type MyClass2[2]
. The new expression returns a pointer to the initial element of this array and you assign that pointer to w
.
w[1].check();
This treats w
as a pointer to an array of MyClass
objects, not as an array of MyClass2
objects.
You cannot treat an array of derived class objects as if it were an array of base class objects. If you want to be able to use the derived-class objects, you need an array of pointers:
MyClass** w = new MyClass*[2];
w[0] = new MyClass2;
w[1] = new MyClass2;
As an extension of @James McNellis and @Nawaz proposed solutions (which are correct), you can avoid a lot of confusion by using container classes you have available to you and smart pointers. Namely std::vector
and std::array
(depending on your compiler version, this may be in the tr1
namespace or you may need to download the boost library to use it) and shared_ptr
(there are others you could choose from as well, though).
Since James appears to be disappear, I think I should post the correct solution:
MyClass** w = new MyClass*[2]; //Note the difference from James solution!
w[0] = new MyClass2;
w[1] = new MyClass2;
std::cout << "Calling w[0].check\n"; w[0].check();
std::cout << "Calling w[1].check\n"; w[1].check();
This should work!
精彩评论