虚函数在继承中表现得很奇怪?

Mr.*_*bis 1 c++ inheritance

Lemme通过给出一个例子来解释我的问题:

#include <iostream>

class PC
{
public:
    PC():Data(0)
    {
    }
    virtual void display()
    {
        std::cout<<"The data is :"<<Data<<std::endl;
    }
protected:
    int Data;
};

class SmartPC:private PC
{
public:
    SmartPC():PC()
    {
    }
    void convert()
    {
        PC* temp=static_cast<PC*>(this);
        temp->display();
    }
    void display()
    {
        std::cout<<"The data is (in bb):"<<a<<std::endl;
    }
};

int main()
{
    SmartPC SmrtPC;
    PC* miniPC= static_cast<PC*>(&SmrtPC);
    SmrtPC.convert();
}
Run Code Online (Sandbox Code Playgroud)

根据Scott Meyers的说法:static_cast<PC*>(this);将创建SmartPC的临时基础副本.但是temp->display();执行了display()派生类的功能.为什么会这样?它不应该执行base的功能display(),因为该对象现在完全是SmartPC基础的副本吗?

另一个问题是,如果我temp->data;convert()函数中添加行,它说 PC::Data是受保护但我从派生类范围访问它SmartPC,那么为什么它不起作用?

任何帮助表示赞赏.

Mat*_*lia 5

根据scott meyers的说法:static_cast<PC*>(this);将创建SmartPC的临时基础副本.但是temp->display();执行display()派生类的功能为什么会这样呢?它应该执行base的功能display(),因为该对象现在完全是SmartPC基础的副本.

没有创建副本,您只是投射指针.

由于该类是多态的,virtual通过指针调用函数会导致调用函数的"正确"版本(根据对象的动态类型,即SmartPC *).

相反,如果display没有virtual,基类的版本将被调用,因为对于非virtual方法它是静态类型的指针,以确定哪个版本被调用.

(displayvirtualSmartPC即使不是明确指定,则virtual覆盖继承预选赛时暗示virtual功能)


请注意,如果您这样做:

PC temp(*this);
Run Code Online (Sandbox Code Playgroud)

你实际上已经创建了一个当前对象的副本,"切成"为一个类型的对象PC.这称为"对象切片",由复制构造函数执行PC; 大多数情况下,这是不受欢迎的行为(因为派生类的对象实际上成为基类的对象,并且多态性不像某些人预期的那样工作).


另一个问题是,如果我temp->data;convert()函数中添加行,它说PC::Data是受保护但我从派生类范围访问它SmartPC,那么为什么它不起作用?

从概念上讲,当您尝试访问时,您尝试访问另一个对象temp->dataprivate成员(temp实际上并不重要this),因此拒绝访问.您访问protected成员的"派生类权限" 仅适用于this.