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

Posted

技术标签:

【中文标题】为啥指向基类的派生类指针可以调用派生类成员函数? [复制]【英文标题】:Why derived class pointer which points to base class can call derived class member function? [duplicate]为什么指向基类的派生类指针可以调用派生类成员函数? [复制] 【发布时间】:2020-10-29 02:16:01 【问题描述】:
#include <iostream>
using namespace std;

struct Base 
    void doBase() 
        cout << "bar" << endl;
    
;

struct Derived : public Base 
    void doBar() 
        cout << "bar" << endl;
   
;

int main()

    Base b;
    Base* b_ptr = &b;
    Derived* d_ptr = static_cast<Derived*>(b_ptr);
    d_ptr->doBar(); //Why there is no compile error or runtime error?
    return 0;

这个程序的输出是bar\n

d_ptr 在调用派生类成员函数时实际上指向一个基类。

这是未定义的行为还是其他?

【问题讨论】:

"为什么没有编译错误或运行时错误?" 为什么会有?简单地说,这是未定义的行为。 回复:“为什么没有编译错误或运行时错误?” ——只是运气不好。程序的行为是未定义的,有时结果是程序按照您的期望执行。直到没有。 【参考方案1】:

是的,这是未定义的行为。

没有编译时错误,因为您使用了static_cast - 这是一种告诉编译器“我比您更了解类型”的方法。你告诉你的对象是Derived。您对编译器撒谎 - 因此是未定义的行为。

因为doBar() 不使用任何Derived 成员,所以它恰好起作用。

【讨论】:

好的。但后来我在派生类中添加了一个int a = 3;,在doBar() 中添加了cout &lt;&lt; a &lt;&lt; endl;。再次没有错误。它只是给了我垃圾价值。 所以“垃圾值”对你来说不是错误吗?您希望程序以错误消息终止吗?那将是定义的行为。未定义的行为意味着程序可以做任何事情。 @Rick --“未定义的行为”仅表示语言定义没有告诉您程序做什么。这并不意味着坏事发生,只是坏事可能发生。 @PeteBecker 好的:P

以上是关于为啥指向基类的派生类指针可以调用派生类成员函数? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

基类与派生类的指针和成员函数调用原理

关于C++基类、派生类的引用和指针

在 C++ 中将指向基类的指针传递给派生类的成员函数

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

在 C++ 继承中,当指向基类的指针对象指向派生类时,不调用派生类析构函数

6多态性-3虚函数