вектор объектов - PullRequest
       57

вектор объектов

0 голосов
/ 05 января 2010

Я попытался добавить объекты в вектор «содержимого» и использовать show () для всех из них. Но объекты, являющиеся потомками (A, B) объекта «Base», ведут себя так же, как объекты типа «Base», что не является моим намерением. Кажется, я пытался использовать виртуальные функции, но это не работает.

Я надеюсь, что код будет говорить сам за себя.

class Base {
    public:
        virtual void show() { cout << "Base "; }
};

class A : public Base {
    public:
        virtual void show() { cout << "A "; }
};

class B : public Base {
    public:
        virtual void show() { cout << "B"; }
};



vector<Base> content;

void add(Base &o) {
    content.push_back(o);
}

A test1;
B test2;

add(test1);
add(test2);

for (size_t i = 0; i < content.size(); i++) {
        collection[i].show(); // output is: Base Base instead of A B
}   

Заранее спасибо.

Ответы [ 5 ]

3 голосов
/ 05 января 2010

То, что у вас есть, является вектором базы.
Когда вы добавляете что-то к вектору, оно копируется в вектор. Но копируется только базовая часть. Таким образом, вы потеряете всю информацию о себе.

Это условно называется проблемой нарезки.

Простое решение - хранить указатели в векторе.

2 голосов
/ 05 января 2010

Как уже говорили другие, вы испытываете нарезку. vector хранит Base, и любая производная информация выделяется.

Облегчите это с помощью указателей:

std::vector<Base*> v;
v.push_back(new A);
v.push_back(new B);

Проблема сейчас в том, чтобы высвободить ваши ресурсы. Прежде чем вектор выйдет из области видимости, вам нужно будет пройти через него и удалить каждый элемент. Еще хуже проблема с исключениями.

Если в любой момент времени существования вектора, если будет сгенерировано исключение, он размотает стек, в какой-то момент освободив все ваши указатели в векторе; одна гигантская утечка памяти.

Если вы используете более выделенный контейнер, вы избежите этой проблемы. Либо напишите один самостоятельно (конечно, не рекомендуется), либо используйте контейнеры с указателем буста .

1 голос
/ 05 января 2010

STL контейнеры хранят объект значения. То, что у вас здесь, называется нарезка .

0 голосов
/ 05 января 2010

Вы должны использовать vector<Base*>, потому что в настоящее время объекты, которые вы передаете в add, будут скопированы в новый объект типа Base.

0 голосов
/ 05 января 2010
vector<Base*> content; // <<

void add(Base *o) { // <<
    content.push_back(o);
}

A test1;
B test2;

add(&test1); // <<
add(&test2); // <<

for (size_t i = 0; i < content.size(); i++) {
        collection[i]->show(); // <<
}   
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...