5

私はC++で書かれたこのコードに出くわしました:

#include<iostream>
using namespace std;

class Base {
public:
    virtual int fun(int i) { cout << "Base::fun(int i) called"; }
};

class Derived: public Base {
private:
    int fun(int x)   { cout << "Derived::fun(int x) called"; }
};

int main()
{
    Base *ptr = new Derived;
    ptr->fun(10);
    return 0;
}

出力:

 Derived::fun(int x) called 

次の場合:

#include<iostream>
using namespace std;

class Base {
public:
    virtual int fun(int i) { }
};

class Derived: public Base {
private:
    int fun(int x)   {  }
};
int main()
{
    Derived d;
    d.fun(1);
    return 0;
} 

出力

Compiler Error.

なぜこれが起こっているのか誰かが説明できますか?最初のケースでは、プライベート関数がオブジェクトを介して呼び出されています。

4

2 に答える 2

4

最初のケースでは、パブリックであるからの宣言を使用しており、呼び出しが実装Baseに遅れてバインドされているためです。Derived継承でアクセス指定子を変更することは危険であり、ほとんどの場合回避できることに注意してください。

于 2012-09-22T19:46:00.517 に答える
3

最初のケースではポリモーフィズムが起こっています。動的バインディングまたは遅延バインディングが発生します。そして、2番目の答えで述べたように、それは時々非常に危険になる可能性があります。

クラス定義の外部からクラスのプライベートインターフェイスに直接アクセスすることはできません。質問のタイトルが示すように、フレンド関数を使用せずに2番目のインスタンスでプライベート関数にアクセスする場合は、クラスで別のパブリック関数を作成します。その関数を使用して、このプライベート関数を呼び出します。このような。

 int call_fun (int i) ;

その中から呼び出しfun()ます。

int call_fun (int i)
{
  return fun (i) ;  //something of this sort, not too good
}

別の関数を呼び出すためだけに使用されるこのような関数は、として知られていwrapper functionsます。

作るfriendsことも常にお勧めできるわけではありません。それは情報隠蔽の原則に反します。

于 2012-09-22T19:47:16.180 に答える