1、问题描述
如果在基类中虚函数是public,子类中重载时标记为protected或者private函数,是否还能访问这个函数?
答案是:
基类指针指向子类时,可以访问,并且访问的是子类重载后的函数;
子类指针肯定不能访问,直接受protected、private限制。
下面测试代码演示了上面的结论,并且顺便演示了一下,基类或子类如何访问基类的虚函数。
2、测试代码
#include <QCoreApplication>
#include <QDebug>
class BaseClass{
public:
BaseClass(){ qDebug() << "BaseClass constructor"; }
virtual ~BaseClass() ;
virtual void publicFun() { qDebug() << "BaseClass publicFun"; }
virtual void basePublic_SubProtectedFun() { qDebug() << "BaseClass basePublic_SubProtectedFun"; }
virtual void basePublic_SubPrivateFun() { qDebug() << "BaseClass basePublic_SubPrivateFun"; }
protected:
virtual void protectedFun() { qDebug() << "BaseClass protectedFun"; }
private:
virtual void privateFun() { qDebug() << "BaseClass privateFun"; }
};
BaseClass::~BaseClass()
{
qDebug() << "BaseClass destructor";
}
class SubClass : public BaseClass{
public:
SubClass(){ qDebug() << "SubClass constructor"; }
virtual ~SubClass() ;
virtual void publicFun() { qDebug() << "SubClass publicFun"; }
protected:
void protectedFun() { qDebug() << "SubClass protectedFun"; }
void basePublic_SubProtectedFun() { qDebug() << "SubClass basePublic_SubProtectedFun"; }
private:
void privateFun() { qDebug() << "SubClass privateFun"; }
void basePublic_SubPrivateFun() { qDebug() << "SubClass basePublic_SubPrivateFun"; }
};
SubClass::~SubClass()
{
qDebug() << "SubClass destructor";
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug() << "多态:基类指针指向子类,可以调用子类的保护或者私有函数";
BaseClass *baseSub = new SubClass;
baseSub->publicFun();
baseSub->BaseClass::publicFun();
baseSub->basePublic_SubProtectedFun(); //在基类中是public,所以可以调用,并且调用的是子类的protected
baseSub->BaseClass::basePublic_SubProtectedFun(); //在基类中是public,所以可以调用,并且调用的是子类的protected
baseSub->basePublic_SubPrivateFun();
baseSub->BaseClass::basePublic_SubPrivateFun();
delete baseSub;
SubClass *sub = new SubClass;
sub->publicFun();
sub->BaseClass::publicFun();
// sub->basePublic_SubProtectedFun(); //因为是保护成员函数,所以不能调用
sub->BaseClass::basePublic_SubPrivateFun();
// sub->basePublic_SubPrivateFun(); //因为是私有成员函数,所以不能调用
sub->BaseClass::basePublic_SubProtectedFun();
delete sub;
return a.exec();
}
打印输出
BaseClass constructor
SubClass constructor
SubClass publicFun
BaseClass publicFun
SubClass basePublic_SubProtectedFun
BaseClass basePublic_SubProtectedFun
SubClass basePublic_SubPrivateFun
BaseClass basePublic_SubPrivateFun
SubClass destructor
BaseClass destructor
BaseClass constructor
SubClass constructor
SubClass publicFun
BaseClass publicFun
BaseClass basePublic_SubPrivateFun
BaseClass basePublic_SubProtectedFun
SubClass destructor
BaseClass destructor