Downcast Base класса на несколько "поколений" вперёд
Имеется класс A, от него наследуется класс B, от которого наследуется класс C. Как произвести приведение типов из A в C?
Код, с которым провожу эксперименты:
#include <iostream>
#include <string>
#include <memory>
using namespace std;
class A
{
public:
string str;
A(string _str)
{
str = _str;
}
virtual ~A(){}
};
class B : public A
{
public:
virtual string unpack(string t) = 0;
virtual ~B(){}
};
class BA : public B
{
public:
string unpack(string t) override
{
string temp = "a";
return temp + str + t;
}
virtual ~BA(){}
};
class BB : public B
{
public:
string unpack(string t) override
{
string temp = "a";
return temp + str + t;
}
virtual ~BB(){}
};
template <typename TypeC>
TypeC *convert(A *_msg)
{
auto msg = dynamic_cast<TypeC*>(_msg);
return msg;
}
int main()
{
A* a = new A("TEST_A");
auto ba = convert<BA>(a);
cout << ba->unpack("TEST_BA") << endl;
return 0;
}
Ответы (1 шт):
Конечно же, вы не можете привести реальный объект A к типу AB!
А вот AB через указатель на A - можете.
Только надо дописать конструкторы...
class A
{
public:
string str;
A(string _str)
{
str = _str;
}
virtual ~A(){}
};
class B : public A
{
public:
B(string _str):A(_str){}
virtual string unpack(string t) = 0;
virtual ~B(){}
};
class BA : public B
{
public:
BA(string _str):B(_str){}
string unpack(string t) override
{
string temp = "a";
return temp + str + t;
}
virtual ~BA(){}
};
class BB : public B
{
public:
string unpack(string t) override
{
string temp = "a";
return temp + str + t;
}
virtual ~BB(){}
};
template <typename TypeC>
TypeC *convert(A *_msg)
{
auto msg = dynamic_cast<TypeC*>(_msg);
return msg;
}
int main()
{
A* a = new BA("TEST_A");
auto ba = convert<BA>(a);
cout << ba->unpack("TEST_BA") << endl;
return 0;
}
Вот оно, главное -
A* a = new BA("TEST_A");
Т.е. указатель на A указывает на самом деле на объект BA - и вот такой указатель вы можете привести к указателю на BA.
А вот если вы создали объект A - то как вы себе представляете приведение его к наследнику? У него же просто нет нужной функции unpack...
Чтобы убедиться - вам надо было в своем коде проверить результат преобразования:
A* a = new A("TEST_A");
auto ba = convert<BA>(a);
cout << ba << endl;
И вы бы увидели, что преобразование не выполнено: ba == nullptr...