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();
}
根据Scott Meyers的说法:static_cast<PC*>(this);
将创建SmartPC的临时基本副本。但是temp->display();
执行了派生类的display()
函数。为什么会这样?它不应该执行base display()
的功能,因为该对象现在完全是SmartPC基础的副本吗?
另一个问题是,如果我在temp->data;
函数中添加行convert()
,它会说
PC::Data
受到保护,但我是从派生类范围访问它,即SmartPC
,为什么它不起作用?
感谢任何帮助。
答案 0 :(得分:5)
根据scott meyers的说法:
static_cast<PC*>(this);
将创建SmartPC的临时基本副本。但temp->display();
执行派生类的display()
函数为什么会这样?它应该执行basedisplay()
的功能,因为该对象现在完全是SmartPC基础的副本。
没有创建副本,您只是将一个指针。
由于类是多态的,通过指针调用virtual
函数会导致调用函数的“正确”版本(根据对象的动态类型,这是SmartPC *
)。
相反,如果display
不是virtual
,则会调用基类的版本,因为对于非virtual
方法,它是静态类型用于确定要调用哪个版本的指针。
(display
virtual
也在SmartPC
,即使未明确指定,在覆盖继承的virtual
函数时隐含virtual
限定符
请注意,如果您这样做:
PC temp(*this);
您实际上已经创建了当前对象的副本,“切片”为PC
类型的对象。这称为“对象切片”,由PC
的复制构造函数执行;通常这是不受欢迎的行为(因为派生类的对象实际上成为基类的对象,并且多态性不像某些人所期望的那样工作)。
另一个问题是,如果我在
temp->data;
函数中添加行convert()
,它会说PC::Data
受到保护,但我从派生类范围即SmartPC
访问它,为什么它不起作用?
从概念上讲,当您尝试访问temp->data
时,您尝试访问其他对象的private
成员(temp
实际上this
并不重要),所以访问被拒绝。您访问protected
成员的“派生类权限”仅适用于this
。
答案 1 :(得分:1)
它不是类的副本,它是对基类对象的引用,因此,它的行为与其他任何类似。
您无法访问受保护成员的原因是您使用了私有继承。