1

Possible Duplicate:
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;
}

The output of the program is "D::show() called.", which means the virtual function declared in the private part of class D is invoked. Don't you think it weird? How could a private member of a class be accessed from outside?

4

3 に答える 3

6

重要な部分は、関数void fun(B&obj)が static 型の引数を取ることですB&(そのため、呼び出しサイトで変換が発生します。同じことが で発生しB*ます)。

B::show public であるため、コードを問題なく呼び出すことができます。コンパイラが呼び出しをディスパッチする方法を見ると、それshowvirtualそうであることがわかりますD::show。タイプのD::show場合に呼び出すことができなかったという事実は無関係です。objD

于 2012-04-18T11:36:00.063 に答える
6

Java とは異なり、C++ ではアクセス指定子は関数に影響しませんvirtual
「アクセス指定子」は、ハンドルの型に関してクラスメソッドで行われるコンパイル時のチェックです。staticたとえば、コード内objのタイプはBand B::show()ispublicです。したがって、コードは合法です。
objは、 以外の型を動的に参照する場合がありますB

virtual関数のディスパッチは実行時の現象であることを思い出してください。(Java では、実行時エラーが発生します。)

B::show()呼び出されると、機能が開始され、適切なオブジェクトの関数がpublic呼び出されます。virtual

直接呼び出そうとD::show()すると、予想されるコンパイラ エラーが発生します。

于 2012-04-18T11:32:29.007 に答える
2

変じゃない。ではB、メソッドは public です。オブジェクトを呼び出すことができます。show()B

メソッドが拡張クラスにディスパッチされるだけです。

于 2012-04-18T11:31:53.517 に答える