Проблема выделения массива производного класса с новым - PullRequest
0 голосов
/ 11 февраля 2011

У меня есть простая программа

$ 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 << "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

Я думал, что можно использовать new для размещения объектов производного класса. Кроме того, v-> check (), кажется, работает нормально.

Ответы [ 3 ]

5 голосов
/ 11 февраля 2011
w = new MyClass2[2]; 

Создает массив из двух MyClass2 объектов.Это типа MyClass2[2].Новое выражение возвращает указатель на начальный элемент этого массива, и вы присваиваете этот указатель w.

w[1].check();  

. Это обрабатывает w как указатель на массив MyClass объектов1010 * не как массив MyClass2 объектов.

Вы не можете обрабатывать массив объектов производного класса, как если бы он был массивом объектов базового класса.Если вы хотите использовать объекты производного класса, вам нужен массив указателей:

MyClass** w = new MyClass*[2];
w[0] = new MyClass2;
w[1] = new MyClass2;
2 голосов
/ 11 февраля 2011

Являясь расширением предлагаемых решений @James McNellis и @Nawaz (которые являются правильными), вы можете избежать путаницы, используя доступные вам классы контейнеров и умные указатели.А именно std::vector и std::array (в зависимости от версии вашего компилятора, это может быть пространство имен tr1 или вам может понадобиться загрузить библиотеку boost, чтобы использовать его) и shared_ptr (есть и другие, которые вы можете выбрать какну хоть).

1 голос
/ 11 февраля 2011

Поскольку Джеймс, кажется, исчезает, я думаю, что я должен опубликовать правильное решение:

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();

Это должно работать!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...