开发者

Problem allocating derived class array with new

开发者 https://www.devze.com 2023-02-10 13:44 出处:网络
I have a simple program $ cat a.cpp #include <iostream> class MyClass { public: virtual void check() {

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!

0

精彩评论

暂无评论...
验证码 换一张
取 消