dynamic_cast中的模棱两可的转换
Ambiguous conversion in 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
首先,这不是模板问题。如果您删除模板并只print_type
D*
,您将看到错误仍然存在。
正在发生的事情是您不使用虚拟继承,因此您会遇到这种情况:
A A
| |
B C
/
D
dynamic_cast不知道你指的是哪A
。
要实现这一点:(我假设这是你想要的)
A
/
B C
/
D
。您应该使用虚拟继承,因此:
class A
{
};
class B : virtual public A
{
};
class C : virtual public A
{
};
class D : public C,public B
{
};
。现在它可以毫无问题地编译:)(请记住,虚拟继承是邪恶的)
这被称为致命的死亡钻石,或者简单地说,钻石问题。通往 A 的"路径"可以经过 B 或 C,因此存在潜在的矛盾。
此外,模板的想法是使其通用,而不是类型感知。模板本身不是编译的代码,它是根据其使用进行编译的。这很像一个大宏。
考虑获取对象作为参数并打印其类型的问题:
叹息。。。使用 RTTI。
#include <iostream>
#include <string>
#include <typeinfo>
template<class T> void print_type(const T& info){
std::cout << typeid(info).name() << std::endl;
}
int main(int argc, char** argv){
D d;
int a = 3;
std::string test("test");
print_type(d);
print_type(a);
print_type(test);
return 0;
}
为了使类多态,你应该定义虚拟析构函数
在您的情况下,发生错误是因为您尝试将dyamic_cast
应用于没有虚拟析构函数的std::string
。
尚未发现的错误是,您情况下的类A
也不是多态的,因此整个层次结构不适合dynamic_cast
。
- 防止主数据类型C++的隐式转换
- 模板参数替换失败,并且未完成隐式转换
- 努力将整数转换为链表。不知道我在这里做错了什么
- HEX值到wchar_t字符(UTF-8)的转换
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将 Qvector<uint8_t> 转换为 QString
- 如何在cuSparse中使用cusparseXcoo2csr从coo转换为csc
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 在c++中使用nlohmann从类到json的转换
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 将 NULL 转换为长不是模棱两可吗?
- 将一组类转换为类模板并避免构造函数模棱两可
- 转换和移动 ctor 导致对 Clang 和 GCC 4.9.2 的模棱两可的要求
- 转换是模棱两可的.标准隐式转换无法选择强制转换运算符
- 虚拟派生和转换模棱两可
- dynamic_cast中的模棱两可的转换
- 从'QTableWidgetItem* const'到'QChar'的转换..或问...模棱两可
- 处理模棱两可的类型转换/转换的正确方法是什么?