朋友的功能在这里继承吗?

时间:2015-07-22 09:32:25

标签: c++ polymorphism private encapsulation

Derived类中的方法fun()是私有的。当我们通过运行时多态性调用函数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;
}

有人可以解释一下发生了什么吗?

3 个答案:

答案 0 :(得分:2)

首先,您的Derived::fun()也是virtual,因为如果派生类中的函数与基类中的虚函数具有相同的声明,则派生类中的函数会自动获取{ {1}},即使没有明确指定。

其次,通过基类的公共中间函数访问私有虚函数是完全可以的,例如,参见this answer及其链接,尤其是Virtuality by Herb Sutter。示例代码可能类似于

virtual

因此,我认为,您的情况会发生类似情况:#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; } 被允许访问main,但由于虚拟性,此ptr->fun()恰好是{{} 1}}。

UPD :扩展评论

  

但这听起来有点令人担忧......我的意思是,所有的功能   派生自Base类的将拥有自己的私有成员   可以访问Base类的友元函数

不,fun()的朋友不能访问Derived::fun()的所有功能,只能查看可通过Derived指针访问的功能。例如:

Base

只能从main访问Base

class Base { 
    virtual void fun();
    friend int main(); 
}
class Derived: public Base {
    virtual void fun();
    virtual void foo();
    void bar();
}

请注意Derived::fun()函数是有意扩展的,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; } virtual函数的任何覆盖意味着可以通过virtual指针调用该函数;这是Derived函数的主要目的。如果Base使其重写函数virtual,它仍然应该意识到可以通过Derived指针访问该函数,因为这是private函数背后的主要思想。

答案 1 :(得分:1)

Friend函数从不参与继承。

这里发生了什么?
Base类中定义虚方法时,会创建一个虚拟表,其中包含funBase方法的地址。由于Derived类继承了它,因此VTABLE还包含Derivedfun方法的地址。现在,由于mainBase类的友元函数,编译器允许其成员访问main方法,而不管其访问说明符如何。因此,main获取Derived::fun的地址,并在运行时调用Derivedfun

答案 2 :(得分:0)

这种情况正在发生,因为您已将fun声明为虚拟。 在搜索vtable的运行时,它会找到Derived::fun()的条目,因此会跳转到该地址。

但朋友的功能不会被继承,你可以用这个来检查。

class Base {
private:
    virtual void fun() { cout << "Base Fun"; }
    friend int main();
    int z = 20;
};

class Derived : public Base {
private:
    void fun() { cout << "Derived Fun"; }
    int m = 10;
};

int main()
{
    Base *ptr = new Derived;
    ptr->z = 10; //Accepted
    ptr->m = 5; //error
    return 0;
}

此处Derived m的私人成员无法访问。