2012-04-18 29 views
1

可能重复:
Public virtual function derived private in C++为什么成员函数仍然可以被访问,即使它被声明为“私有”?

class B 
{ 
    private: 
    int b; 
    public: 
    B(int i); 
    virtual void show() 
    { 
     cout<<"B::show()called. "<<b<<endl; 
    } 
}; 

B::B(int i=0) 
{ 
    b=i; 
} 

class D:public B 
{ 
    private: 
    int d; 
    void show() 
    { 
     cout<<"D::show() called. "<<d<<endl; 
    } 
    public: 
    D(int i, int j); 
}; 

D::D(int i=0, int j=0):B(i) 
{ 
    d=j; 
} 

void fun(B&obj) 
{ 
    obj.show(); 
} 
/*if I redefine fun() as follow, the result would be the same 
void fun(B*obj) 
{ 
obj->show(); 
} 
*/ 
int main() 
{ 
    D *pd=new D(5,8); 
    fun(*pd);  //K 
    delete pd; 
} 

程序的输出是 “d ::显示()调用。”,这意味着在专用部分中声明的虚拟功能的D类被调用。你不觉得这很奇怪吗?一个班级的私人成员如何从外部访问?

+5

这个问题有999999个重复。 – Puppy 2012-04-18 11:31:43

+0

访问说明符只限制那些从类外部访问的访问。因此,如果你想写一些有趣的(D&)或有趣的(D *),就不能使用静态链接来访问D :: show()。使用具有公共成员show()的基类,您可以通过多态调用获得访问权限,这将通过兄弟实现的障碍。 Ughh! :)我只是试图用更直接的方式来解释它。 – parallelgeek 2012-04-18 11:41:26

回答

2

这并不奇怪。在B中,该方法是公开的。您可以B对象上调用show()

只是将该方法分派给扩展类。

6

与Java不同,在C++中,访问说明符不会影响virtual函数。
“访问说明符”是编译时检查它是在类方法上针对static类型的句柄进行的。例如在您的代码中obj的类型为BB::show()public;因此代码是合法的。
obj可能会动态引用除B以外的其他类型。

请记住,virtual函数调度是运行时现象。 (在Java中它会给出一个运行时错误。)

B::show()public而且一旦它被调用,virtual功能就会启动并调用适当的对象函数。

如果您尝试直接调用D::show(),那么您将得到预期的编译器错误。

+0

“访问说明符不影响虚函数”,您应该编辑此部分。我明白你的意思,但对未经训练的人来说,这可能会令人困惑。 – 2012-04-18 11:50:02

6

关键部分是您的功能void fun(B&obj)采用静态类型B&的参数(因此转换发生在调用站点;同样发生在B*)。

由于B::show公共,您的代码调用它没有问题。当编译器查看如何发送呼叫时,它看到showvirtual,因此它调用D::show。如果objD类型,则不能调用D::show这一事实是无关紧要的。

+0

我发现,如果我将虚函数show()放在基类B的私有部分中,程序将无法编译,提醒虚函数在基类中是私有的,即使派生类中的对象声明了如下所示:#include using namespace std; class A { private: virtual void function(){cout <<“void A :: function()get invoked。”<< endl;} };公共A { public: void function(){cout <<“void B :: function()get invoked。”<< endl;} }; int main(){ \t \t B b; \t b.function(); \t A * a =&b; \t A &ao=b; \t a-> function(); \t ao.function(); } – JDein 2012-04-20 06:31:11

相关问题