为啥不能将父指针分配给子指针?

Posted

技术标签:

【中文标题】为啥不能将父指针分配给子指针?【英文标题】:Why can't a parent pointer be assigned to a child pointer?为什么不能将父指针分配给子指针? 【发布时间】:2021-01-16 07:46:17 【问题描述】:

我有一个简单的继承案例如下:

class Person 
public:
    const char* name;
public:
    Person()
        : name("Unknown person") 
    
    Person(const char* name)
        : name(name) 
;

class Student : public Person 
public:
    Student()
        : Person("Unknown Student") 
;

如果我将一个子指针分配给一个父指针,那是完全合法的:

Student *s = new Student();
Person *p = s;

但是如果我这样做,将父指针分配给子指针,则会导致错误:

Person *p = new Person();
Student *s = p;

错误是:从“Person*”到“Student*”的无效转换。

这可能有用的一个例子是:我有一个 Person 类,并且取决于这个人将在生活中做什么,我会将其转换为 Student、Teacher 等。

有什么建议吗?

【问题讨论】:

不,您将父指针分配给子指针。 阅读虚函数。这是解决此问题的规范方法。 @john: 虚拟与否,人不是学生。所以无论如何都会出错。 【参考方案1】:
Person *p = s;

之所以有效,是因为每个Student 也是一个Person

Student *s = p;

不起作用,因为 Person 不一定是 Student

【讨论】:

不能在发布的代码中使用 dynamic_cast,因为基类不包含任何虚函数。 @john 谢谢你的回复,真的帮了我很多。那么为什么只有虚函数才能使用dynamic_cast呢? @AnhTran 如果一个类有一个或多个虚拟函数,那么编译器会将一个称为 vtable 的东西添加到该类中。这使得类比其他情况大一点(通常它使类大指针的大小)。实现 dynamic_cast 还需要一个 vtable,因此 C++ 规则规定您必须至少有一个虚函数才能使 dynamic_cast 工作。

以上是关于为啥不能将父指针分配给子指针?的主要内容,如果未能解决你的问题,请参考以下文章

尝试在函数内动态分配父指针给子指针会导致分段错误

如何使用 AutoMapper 将父引用分配给子属性

对 NULL 指针连续 free多次会出错吗?为啥?

为啥我们不能定义一个指向 int 指针的低 + *** const 指针?

为啥接口不能用指针接收器实现

指针 分配空间