О типах C ++ и векторах - PullRequest
       22

О типах C ++ и векторах

1 голос
/ 20 августа 2011

Допустим, у меня есть несколько классов

Класс Альфа (Базовый класс)

Класс бета (подкласс альфа) * ​​1005 *

Класс Delta (Подкласс Альфа) * ​​1007 *

Можно ли создать vector<Alpha> и сохранить экземпляры объектов типов Alpha, Beta и Delta в пределах этого вектора и иметь векторную функцию как нормальную?

Если нет, предположим, что я хотел бы иметь какую-то функциональность подобного типа, какой будет наилучший подход?

Ответы [ 2 ]

3 голосов
/ 20 августа 2011

Один из подходов к этому состоит в том, чтобы иметь вектор, полный указателей, и иметь функции, которые являются общими для каждого из них: virtual в базовом классе:

class Alpha {
public:
    virtual void dosomething() { /* do something as an alpha */ }
};

class Beta : public Alpha {
public:
    void dosomething() { /* do something as a beta */ }
};

class Delta : public Alpha {
public:
    void dosomething() { /* do something as a delta */ }
};

vector<Alpha*> v;
v.push_back(new Alpha);
v.push_back(new Beta);
v.push_back(new Delta);

v[1]->dosomething(); // calls Beta's dosomething

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

vector<shared_ptr<Alpha> > v;
v.push_back(shared_ptr<Alpha>(new Alpha));
v.push_back(shared_ptr<Alpha>(new Beta));
v.push_back(shared_ptr<Alpha>(new Delta));

v[1]->dosomething(); // still calls Beta's dosomething

Причина, по которой вы не хотите иметь вектор Alpha с (вместо Alpha* с, которые в порядке), заключается в том, чтоКонтейнеры STL копируют значения, которые вы им даете, и если вы копируете Beta (или Delta) как Alpha, будет вызван только конструктор копирования Alpha, и полученная информация должна будет вписаться вразмер Alpha (который, если вы добавили какую-либо информацию в подкласс, будет недостаточно большим), а дополнительная информация, которую имел Beta (или Delta), будет потеряна.Это называется нарезкой.

1 голос
/ 20 августа 2011

Лучший способ - хранить умные указатели на классы в векторе.

Вы не можете передавать по значению, так как тогда вы получаете нарезку.

Если вы передадите по ссылке, у вас могут быть переменные, выходящие за рамки.

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