C ++: могу ли я разыграть векторк векторуво время вызова функции? - PullRequest
7 голосов
/ 20 февраля 2012

У меня есть класс и функция, которые выглядят так:

Class base_class{
    ...
}

void Func(...,vector<base_class> &vec_b,...){
    // inside the function, the vector vec_b is being re-organized and re-sized
}

и я определил производный класс, который выглядит следующим образом:

Class derived_class: public base_class{
    ...
}

Теперь, не изменяя функцию Func, можно ли передать vector<derived_class> в Func, например:

void main(){
    vector <derived_class> d;
    Func(...,d,...);
}

такой, что производный класс d подвергается той же реорганизации и изменению размеров? Я знаю, что могу без проблем привести производный класс в базовый класс при вызове функции, но однажды с вектором в игру могут возникнуть трудности? Я не могу найти ответ в Интернете, поэтому любые предложения или помощь с благодарностью. спасибо.

Ответы [ 5 ]

3 голосов
/ 20 февраля 2012

Это работает только если вы используете указатели.

Если вы не используете указатели, есть шанс нарезки.Например,

class Base {
  protected:
    int foo;
};

class Child : public Base {
    int bar;
};

* class Base содержит только один int с именем foo, а class Child содержит два целых, foo и bar.

Child f;
Base sliced = (Child)f;

Это отрежет дочерний элемент, заставив его удалить некоторые данные из объекта.Вы не сможете привести родителя обратно в дочерний класс, если только вы не используете указатели.

Итак, если вы изменили vector<>, чтобы указатели указывали вместо экземпляров класса, вы можете переходить туда-сюда между родителем / ребенком.

Используя что-то вроде:

vector<Base*> vec;
vec[0] = static_cast<Base*>(new Child());

...
Func(vec);
...

Позволит вам привести членов вашего вектора в их дочерние классы.

3 голосов
/ 20 февраля 2012

Нет.Даже если A является B, a vector<A> не является vector<B>.

. Чтобы передать один вместо другого, вы можете передать вектор указателей (или использовать Boost ptr_vector).Кроме того, вы можете использовать шаблон, чтобы разрешить передачу вектора чего-либо, что обеспечивает правильный интерфейс.

Любой из этих способов потребует изменения вашей функции, хотя - по сути, нет способа избежать этого (и все жеобеспечить функциональность, которую вы хотите).

2 голосов
/ 20 февраля 2012

номер

Вы можете позволить Func взять vector <base_class*> и позволить точечным элементам в vector <base_class*> указать на derived_class экземпляров.

2 голосов
/ 20 февраля 2012

Нет, вы не можете конвертировать между векторами разных типов. Однако вы можете добиться того, что пытаетесь сделать, сделав Func шаблоном. Вероятно, вам не потребуется изменять какой-либо код в реальном теле функции, но это зависит от того, что вы делаете.

template<typename T>
void Func(..., vector<T> &vec_b, ...){
    // inside the function, the vector vec_b is being re-organized and re-sized
}
0 голосов
/ 20 февраля 2012

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

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