虚拟函数在继承中表现怪异

Virtual function acting weird in inheritance?

本文关键字:函数 继承 虚拟      更新时间:2023-10-16

让我举一个例子来解释我的问题:

#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();
}

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

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

感谢您的帮助。

根据scott-meyers的说法:static_cast<PC*>(this);将创建SmartPC的临时基础副本。而CCD_ 10执行派生类的CCD_?它应该执行base的display()的功能,因为该对象现在完全是SmartPC的base的副本。

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

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

相反,如果display不是virtual,则会调用基类的版本,因为对于非virtual方法,它是指针的静态类型,以确定要调用哪个版本。

(display也是SmartPC中的virtual,即使没有明确指定,在重写继承的virtual函数时也会隐含virtual限定符(


请注意,如果你这样做了:

PC temp(*this);

您实际上已经创建了当前对象的副本,"切片"为PC类型的对象。这被称为"对象切片",由PC的复制构造函数执行;大多数情况下,这是不希望的行为(因为派生类的对象实际上变成了基类的对象,多态性并不像一些人预期的那样起作用(。


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

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

它不是类的副本,它是对基类对象的引用,因此,它的行为与其他任何对象一样具有多态性。

您无法访问受保护成员的原因是您使用了私有继承。