我有一个cpp代码,其中c类是从b类派生的,而b类是从a类派生的。

现在,类b具有一些公共数据成员。因此,我在堆上创建类c的实例,将其指向另一个类的指针作为指向a的指针,然后向下将该指针向下转换为类b的指针,然后打印类b的公共变量。

这是有效的下垂吗?我问是因为仅仅更改编译器就破坏了这个工作代码。

我包括下面的代码片段,其中捕获了我遇到的问题。

#include <iostream>
using namespace std;


class grand
{
};
class parent : public grand
{
    public : parent(){i=0;}
    int i;
    parent(int j){ i = j;}
    void set(int j){i = j;}
};

class child : public parent{


public: child(){};
};

void print ( grand* ptr)
{
    parent *p = (parent*) ptr;
    std::cout << std::endl << p->i << std::endl;
}

int main() {
    // your code goes here
    child c;
    c.set(9);
    print(&c);
    return 0;
}


谢谢

最佳答案

这是有效的下垂吗?


是。您的演员表内部适用static_cast,根据§5.2.9/ 11,它将为您提供正确的结果。如果ptr的参数没有指向parent,则强制转换的结果是不确定的-以下代码的执行也将是不确定的。

C ++中多态类型的向下转换通过dynamic_cast进行。您上面的grand类不是多态的-您必须至少向grand添加一个虚拟析构函数才能使其多态。否则,您将得到以下代码的编译器错误。

parent *p = dynamic_cast<parent*>(ptr); // Once grand is polymorphic...


并检查结果p是否为非零。仅此方法(在运行时)显示强制转换是否起作用!所有其他参数都调用未定义的行为或未定义的非零值。

一些注意事项:


垂头丧气几乎总是不良设计的迹象。如果可能的话,请避免使用虚拟(打印)功能。
print应该使用指向const的指针,因为它不会修改任何数据成员。

关于c++ - 这是有效的垂头丧气,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25769413/

10-09 03:55