为啥从指向基址的指针到指向派生的指针的静态转换“无效”?

Posted

技术标签:

【中文标题】为啥从指向基址的指针到指向派生的指针的静态转换“无效”?【英文标题】:Why is a static_cast from a Pointer to Base to a Pointer to Derived "invalid?"为什么从指向基址的指针到指向派生的指针的静态转换“无效”? 【发布时间】:2011-04-27 18:27:48 【问题描述】:

所以我有这个代码:

Node* SceneGraph::getFirstNodeWithGroupID(const int groupID)

    return static_cast<Node*>(mTree->getNode(groupID));

mTree->getNode(groupID) 返回一个 PCSNode*。 Node 是从 PCSNode 公开派生的。

我在 static_cast 上找到的所有文档都说明了这一点:“static_cast 运算符可用于将指向基类的指针转换为指向派生类的指针等操作。”

然而,XCode 的 (GCC) 编译器表示从 PCSNode* 到 Node* 的 static_cast 无效且不允许。

有什么原因吗?当我将它切换到 C 风格的演员表时,编译器没有抱怨。

谢谢。

更新:即使问题已得到解答,我仍会发布编译器错误以确保完整性,以防其他人遇到同样的问题:

错误:语义问题:Static_cast 从 'PCSNode *' 到 'Node *' 不是 允许

【问题讨论】:

你能说出确切的编译器错误吗?只是为了确保那里没有任何与 const 相关或类似的东西。 (根据您描述的信息应该可以) "Node 是从 PCSNode 公开派生的"???我猜你的意思是“PCSNode 是从Node 公开派生的”,这与“NodePCSNode 的基类”相同。对吗? PCSNode 实际上是基类,因为它包含树的指针,Node 是一个可以在树中的转换节点。 【参考方案1】:

原因很可能是 Node 的定义对编译器不可见(例如,它可能只是前向声明的:class Node;)。

独立示例:

class Base ;

class Derived; // forward declaration

Base b;

Derived * foo() 
    return static_cast<Derived*>( &b ); // error: invalid cast


class Derived : public Base ; // full definition

Derived * foo2() 
    return static_cast<Derived*>( &b ); // ok

【讨论】:

由于循环依赖问题导致定义不可用怎么办?还可以进行某种类型的演员表吗? 总是有 reintepret_cast,如果你正在转换指针,它会起作用,因为它们的大小相同。

以上是关于为啥从指向基址的指针到指向派生的指针的静态转换“无效”?的主要内容,如果未能解决你的问题,请参考以下文章

为啥C ++允许将指向基对象的指针转换为派生类的指针[重复]

为啥指向基类的派生类指针可以调用派生类成员函数? [复制]

为啥我可以通过指向派生对象的基类指针访问派生私有成员函数?

自动将指向派生类的指针列表转换为指向基类的指针列表

为啥基类指针指向基类中的纯虚方法,而不是派生类中的覆盖方法?

基类指针指向派生类对象&派生类指针指向基类对象