我正在尝试使用 pimpl 习语。特别是,实现类将实现另一个接口(interface):
// public_class.h
class PublicClass
{
public:
/* public interfaces here */
private:
class _PublicClass_impl;
friend class _PublicClass_impl;
protected:
_PublicClass_impl * const _impl;
};
// public_class.cpp
class PublicClass::_PublicClass_impl : public SomeInterface
{
friend class PublicClass;
/* all sort of stuff ... */
};
我的问题是,在以下情况下可以使用什么转换?
// some_other_class.h
class SomeOtherClass : private PublicClass
{
void some_function()
{
// definition of _PublicClass_impl is unknown
// thus, _impl is opaque
SomeInterface * interface = dynamic_cast<SomeInterface *>(_impl); //??
/* more code ... */
}
};
在这种情况下 dynamic_cast 可以正常工作吗?在这种情况下是否可以使用任何其他类型的转换?
最佳答案
据我所知,没有一种优雅的方式可以做你想做的事。 reinterpret_cast 或 c-style cast 可能有效(行为未指定),但当它允许您完全编译时,其他都是未定义的行为。
n3242 的 5.2.7.2(我知道这不是官方标准,但应该接近)说了 dynamic_cast(v),
如果 T 是指针类型,则 v 应是指向完整类类型的指针的纯右值,结果是类型 T 的纯右值。如果 T 是左值引用类型,则 v 应是完整类的左值类型,结果是 T 引用的类型的左值。如果 T 是右值引用类型,则 v 应该是具有完整类类型的表达式,结果是 T 引用的类型的 xvalue。
所以 dynamic_cast 不起作用。
static_cast 不起作用,因为在这两种类型之间没有定义任何有效的转换。
5.2.10.7 说到 reinterpret_cast(v),
指向对象的指针可以显式转换为指向不同对象类型的指针。69 当“指向 T1 的指针”类型的纯右值 v 转换为“指向 cv T2 的指针”类型时,结果为 static_cast( static_cast(v)) 如果 T1 和 T2 都是标准布局类型 (3.9),并且 T2 的对齐要求不比 T1 严格。将“指向 T1 的指针”类型的纯右值转换为“指向 T2 的指针”类型(其中 T1 和 T2 是对象类型,并且 T2 的对齐要求不比 T1 的对齐要求更严格)并返回其原始类型会产生原始类型指针值。任何其他此类指针转换的结果均未指定。
所以 reinterpret_cast 可能会起作用。
最后,不使用强制转换是行不通的,因为编译器不知道类型之间的关系。
关于c++ - 向上转换不透明指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10158925/