虚拟函数在继承中表现怪异
Virtual function acting weird in inheritance?
让我举一个例子来解释我的问题:
#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
。
它不是类的副本,它是对基类对象的引用,因此,它的行为与其他任何对象一样具有多态性。
您无法访问受保护成员的原因是您使用了私有继承。
- C++虚函数继承
- 名称隐藏对静态函数继承的实例使用
- C++ std::vector 中的虚拟析构函数继承
- 具有相同名称的类的构造函数继承
- 多复制构造函数继承中的惊人行为
- CRTP 和复制/移动赋值/构造函数继承
- 复制构造函数继承动态分配的数组
- 谷神星求解器成本函数继承错误:模板可能不是虚拟的
- 无法从 c++ 中的构造函数继承
- 在构造函数继承中使用默认构造函数
- 如何定义从虚拟函数继承的静态函数
- 调用超类函数继承 c++
- 构造函数继承和直接成员初始化
- c++ 不明确的双非虚函数继承
- C++ - 使用私有参数的构造函数继承
- 通过可变参数模板进行C++11构造函数继承
- 使用模板进行函数继承
- C++11构造函数继承和不带参数的构造函数
- 函数继承问题
- C++11 - 构造函数继承