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,那么为什么它不起作用?
任何帮助表示赞赏.
根据scott meyers的说法:
static_cast<PC*>(this);将创建SmartPC的临时基础副本.但是temp->display();执行display()派生类的功能为什么会这样呢?它应该执行base的功能display(),因为该对象现在完全是SmartPC基础的副本.
没有创建副本,您只是投射指针.
由于该类是多态的,virtual通过指针调用函数会导致调用函数的"正确"版本(根据对象的动态类型,即SmartPC *).
相反,如果display没有virtual,基类的版本将被调用,因为对于非virtual方法它是静态类型的指针,以确定哪个版本被调用.
(display是virtual也SmartPC即使不是明确指定,则virtual覆盖继承预选赛时暗示virtual功能)
请注意,如果您这样做:
PC temp(*this);
Run Code Online (Sandbox Code Playgroud)
你实际上已经创建了一个当前对象的副本,"切成"为一个类型的对象PC.这称为"对象切片",由复制构造函数执行PC; 大多数情况下,这是不受欢迎的行为(因为派生类的对象实际上成为基类的对象,并且多态性不像某些人预期的那样工作).
另一个问题是,如果我
temp->data;在convert()函数中添加行,它说PC::Data是受保护但我从派生类范围访问它SmartPC,那么为什么它不起作用?
从概念上讲,当您尝试访问时,您尝试访问另一个对象temp->data的private成员(temp实际上并不重要this),因此拒绝访问.您访问protected成员的"派生类权限" 仅适用于this.