Рассмотрит проблему получения объекта в качестве аргумента и печати его типа:Неоднозначность преобразования в dynamic_cast
#include <iostream>
class A { };
class B : public A { };
class C : public A { };
class D : public C, public B { };
using namespace std;
template<class T>
void print_type(T* info)
{
if(dynamic_cast<D*>(info))
cout << "D" << endl;
else if(dynamic_cast<C*> (info))
cout << "C" << endl;
else if(dynamic_cast<B*>(info))
cout << "B" << endl;
else if(dynamic_cast<A*> (info))
cout << "A" << endl;
}
int main(int argc, char** argv)
{
D d;
print_type(&d);
return 0;
}
Это дает мне следующее сообщение об ошибке: "неоднозначного преобразования из производного класса„D“для базового класса. "
Но я не вижу, где двусмысленность: если объект, объявленный в main (d), имеет тип D, почему он не может быть напрямую преобразован в тип A?
Кроме того, если я передать аргумент типа строки я, конечно, получить другие ошибки:
'std::basic_string<char>' is not polymorphic
В Java для дженериков есть синтаксис: <T extends A>
; в этом случае это было бы полезно. Как я могу сделать аналогичную вещь в C++ с шаблонами?
Я изменил код таким образом:
#include <iostream>
#include <vector>
class A { };
class B : virtual public A { };
class C : virtual public A { };
class D : public C, public B { };
using namespace std;
template<class T>
void print_type(T* info)
{
if(dynamic_cast<D*>(info))
cout << "D" << endl;
else if(dynamic_cast<C*> (info))
cout << "C" << endl;
else if(dynamic_cast<B*>(info))
cout << "B" << endl;
else if(dynamic_cast<A*> (info))
cout << "A" << endl;
}
int main(int argc, char** argv)
{
string str;
print_type(&str);
return 0;
}
Но я все еще получаю ошибку: 'std::basic_string<char>' is not polymorphic
Я предполагаю, что это всего лишь иллюстративный пример, а не настоящий код? Разумеется, это именно то, что решено полиморфизмом. –
Это не иллюстративно, но я попробовал этот код, чтобы посмотреть, как работает dynamic_cast. –
@RamyAlZuhouri См. [MSDN] (http://msdn.microsoft.com/en-us/library/4k5yex0s%28v=vs.71%29.aspx) об этом. «Вы не можете использовать dynamic_cast для преобразования из неполиморфного класса (класса без виртуальных функций)». – MPelletier