Динамическое приведение, преобразование списка объектов, шаблоны - PullRequest
0 голосов
/ 19 февраля 2011

Есть 2 класса:

class A
{
   private:
        double a1, a2;
   ...
};

class B : public A
{
   private:
        double b1, b2;
};

и универсальный контейнер

template <typename Item>
struct TList
{
    typedef std::vector <Item> Type;
};


template <typename Item>
class GList
{
private:
            typename TList <Item>::Type items;

};

Там 4 контейнера объектов

GList <A> A1;
GList <B> B1;
GList <A*> A2;
GList <B*> B2;

Разрешены или нет эти преобразования (вверх / вниз):

1] GList <B> B3 = dynamic_cast <GList <B> &> (A1);
2] GList <A> A3 = static_cast <GList <A> &> (B1);
3] GList <B*> B4 = dynamic_cast <GList <B*> &> (A2);
4] GList <A*> A4 = static_cast <GList <A*> &> (B2);

Есть ли способ как преобразовать список объектов в список родительских объектов и наоборот?

Обновленный вопрос

А как насчет reinterpret_cast?

1] GList <B> B3 = reinterpret_cast <GList <B> &> (A1);
2] GList <A> A3 = reinterpret_cast <GList <A> &> (B1);
3] GList <B*> B4 = reinterpret_cast <GList <B*> &> (A2);
4] GList <A*> A4 = reinterpret_cast <GList <A*> &> (B2);

Ответы [ 5 ]

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

По сути, контейнеры не ковариантны ;нет никакой связи между std::vector<Base> и std::vector<Derived> (равно как и между std::vector<Base *> и std::vector<Derived *>.

. В случае контейнеров типа значения есть фундаментальная проблема, которая обычно sizeof(Derived) > sizeof(Base).Таким образом, все математические операции с внутренним указателем в std::vector будут ужасно сломаны, если вы попытаетесь привести один к другому.

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

0 голосов
/ 19 февраля 2011

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

GList<A>& a = convert_the_thing(B1);
a.add_a_element(A());

и я бы вставил A в ваш список B.

0 голосов
/ 19 февраля 2011

dynamic_cast и static_cast работают, если объекты имеют отношения (например, A и B).

Но шаблон создает совершенно новый класс, поэтому нет возможности использовать эти приведения.Может быть, вы можете попробовать reinterpret_cast, но это не безопасно ...

0 голосов
/ 19 февраля 2011
GList <B> B3 = dynamic_cast <GList <B> &> (A1);

dynamic_cast работает только с полиморфным типом.Здесь GList не является полиморфным.Следовательно, он даже не будет компилироваться!

Если вы сделаете этот полиморфный, даже тогда это приведение не будет работать, так как между GList<B> и <GList<A> нет никакой связи.Они как два разных несвязанных типа.

На самом деле они связаны так же, как GList_B и GList_A (например, если вы определили два разныхклассы с такими именами).Или, что еще лучше, они связаны так же, как Java и JavaScript, Car и Carpet.

0 голосов
/ 19 февраля 2011

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

...