如何在c++中使用reinterpret_cast转换为派生类指针
how to use reinterpret_cast to cast to a derived class pointer in c++
下面是我的测试示例:
struct base {
virtual ~base(){}
int x;
};
struct derived: public virtual base {
base * clone() {
return new derived;
}
derived(): s("a") {}
std::string s;
};
int main () {
derived d;
base * b = d.clone();
derived * t = reinterpret_cast<derived*>(b);
std::cout << t->s << std::endl;
return 0;
}
它在我打印s的那行崩溃了。因为"b"是指向派生类的指针,reinterpret_cast应该正常工作。我想知道为什么它会崩溃。同时,如果我将reinterpret_cast替换为dynamic_cast,那么它就可以工作了。
即使b
在这里动态类型为derived
,您也必须使用dynamic_cast
。这就是dynamic_cast
的作用,在运行时动态地将基类的指针转换为派生类。
reinterpret_cast
接受原始指针,并认为它是派生类型。然而,由于virtual
的继承,必须对指针做一些调整,以指向正确的方法调度表,这正是dynamic_cast
将要做的。
不要reinterpret_cast
它,它会导致多重继承或虚拟继承的问题,就像您的情况一样。难道一个简单的static_cast
就能完成这里的工作吗?
要知道原因,请搜索虚拟继承的实现。常见的一种方法是在对象中存储基类的指针,这样虚拟基类就不会与其派生类共享相同的地址。在使用多重继承时也有类似的情况。
简而言之,reinterpret_cast
只能将指针转换为int型并返回(如果int型中有足够的大小来容纳指针)。
正如这里的其他答案所建议的那样,您不能以这种方式使用reinterpret_cast
,因为指向base
的指针的值实际上与指向derived
的指针的值不同。有效的指针是在运行时推断出来的,这就是为什么你必须使用dynamic_cast
。static_cast
不能工作,因为您在设计时不知道通过哪个中间类型派生的类(您想转换到的类)是从您有指针指向的类型派生的。
这里真正的问题应该是:我知道在设计时,如何从base
指针计算derived
指针。如何避免(dynamic_cast
的)运行时惩罚?
struct base {
void* const self;
virtual ~base() {}
protected:
base(void* self) : self(self) {}
};
struct derived : public virtual base {
derived() : base(this) {}
}
这是丑陋和危险的,因为它为了性能牺牲了类型安全(如果你真的很幸运,你会得到一个轻微的运行时性能)。但是,您可以将base
指针(void*
类型的self
成员)reinterpret_cast
转换为derived
指针。
- 防止主数据类型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字符矢量(按大端字节顺序)
- 如何理解C++标准N3337中的expr.const.cast子句8
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 如何使用OpenCV将RBG图像转换为HSV,并将H、S和V值保存为C++中的3个独立图像
- 复制列表初始化的隐式转换的等级是多少
- 覆盖 CAST 运算符(我认为它被称为向下转换)
- C++错误,隐 <function-style-cast> 式要求使用模板化类一次调用多个构造函数的多个转换
- 如何修复<function-style-cast>错误:无法从'initializer list'转换为asdending比较<W>(模板函子)
- 错误 C2440: 'type cast':无法从 'bool' 转换为 'CString'
- <function-style-cast> 错误:无法从'initializer list'转换为'std::thread'