Har*_*ris 6 c++ polymorphism encapsulation private
fun()Derived类中的方法是私有的.当我们ptr->fun()通过运行时多态来调用函数时,它正在执行.但这违反了Derived类的封装属性.
#include<iostream>
using namespace std;
class Derived;
class Base {
private:
virtual void fun() { cout << "Base Fun"; }
friend int main();
};
class Derived: public Base {
private:
void fun() { cout << "Derived Fun"; }
};
int main()
{
Base *ptr = new Derived;
ptr->fun();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
有人可以解释一下发生了什么吗?
首先,你的Derived::fun()也是virtual,因为如果派生类中的函数与基类中的虚函数具有相同的声明,则派生类中的函数会自动获取virtual,即使没有明确指定。
其次,通过基类中的公共中间函数访问私有虚拟函数是完全可以的,例如,请参阅此答案及其链接,特别是 Herb Sutter 的 Virtuality。示例代码可能类似于
#include<iostream>
using namespace std;
class Derived;
class Base {
private:
virtual void fun() { cout << "Base Fun"; }
public:
void funInt() { fun(); }
};
class Derived: public Base {
private:
virtual void fun() { cout << "Derived Fun"; }
};
int main()
{
Base *ptr = new Derived;
ptr->funInt();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
因此,我认为,在您的情况下发生的情况是类似的情况:main允许访问ptr->fun(),但由于虚拟性,这fun()恰好是Derived::fun()。
UPD:扩展评论
但这听起来有点令人担忧吗?我的意思是,从 Base 类派生的所有函数都将具有可由 Base 类的友元函数访问的私有成员
不,并不是 的所有函数都Derived可以被 的友元访问Base,而只有那些可以通过Base指针访问的函数。例如:
class Base {
virtual void fun();
friend int main();
}
class Derived: public Base {
virtual void fun();
virtual void foo();
void bar();
}
Run Code Online (Sandbox Code Playgroud)
只能Derived::fun()从 main 访问:
int main() {
Derived *ptr = new Derived;
Base* baseptr = ptr;
baseptr->fun(); // ok, calls Derived::fun()
baseptr->foo(); // error, no such function in Base
ptr->foo(); // error, foo is private
return 0;
}
Run Code Online (Sandbox Code Playgroud)
请注意,virtual函数是有意可扩展的,并且任何对virtual函数的重写都意味着可以通过指针Derived调用该函数;Base这是函数的主要目的virtual。如果Derived使其重写函数private,仍然应该意识到该函数可以通过Base指针访问,因为这是函数背后的主要思想virtual。