仮想機能がプライベートアクセスを破る

c++ virtual
仮想機能がプライベートアクセスを破る

最近、http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic =%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr134.htm [IBMサイトでこの記事に出会いました]。 以下はサンプルコードです

#include "iostream"

class B {
public:
  virtual void f()
  {
    std::cout<<"\n In class B";
  }
};

class D : public B {
private:
    int i;

  void f()
  {
  std::cout<<"\n In class D i = "<f();

  // error, D::f() is private
  //dptr->f();
}

Dのプライベート関数を呼び出すことができるようになりました。

P.S. :仮想機能の仮想機能アクセスセクションに移動してください。 貼り付けたときに正確なリンクが表示されない理由がわかりません。

  2  0


ベストアンサー

呼び出し `bptr→ f()`は、 `bptr`が指すオブジェクトのタイプに応じて、実行時に評価されます。 コンパイル時には、コンパイルは `bptr→ f()`呼び出しを `B

f()`の呼び出しと見なし、 `B :: f()`は `public`なので、コンパイラはエラーのみを報告しません。 実際の関数呼び出し `D :: f()`が評価されるのは実行時のみです。

これは「カプセル化」の原則を壊すものではありません。これは「ランタイムポリモーフィズム」または「ダイナミックポリモーフィズム」と呼ばれるC ++の機能です。

`D

f()は `Private`アクセス指定子の下で宣言されているため、 dptr→ f() `を直接呼び出すことはできず、プライベートに宣言されたメンバーにクラスの外部からアクセスすることはできません。

6


仕様によるものです。

  • B :: f はパブリックです。 * B *へのポインターを介した f のユーザーアクセスが許可されます。 * f *は仮想であるため、呼び出しは派生クラスの f *にディスパッチされます。

    しかし、* D

    f はプライベートであり、ポインターdo * D *を介して f *にアクセスすることはできません。

2


アクセス指定子はコンパイル時の構造体であるため、コンパイラは、オブジェクト(またはポインター)の_static_型に基づいて、コンパイル時に(明らかに)アクセス規則の違反を検出します。 このような違反は実行時に検出できません。

コンパイラは、 bptr`の_static_型が B`であり、 public`関数 f() が定義されているため、式 bptr→ f( ) `はコンパイラのテストに合格します。 したがって、動作します。

しかし、 `dptr→ f()`は動作しません。`dptr`の_static_型はプライベート関数 `f()`を持つ `D`であるため、コードもコンパイルされないからです!

カプセル化に違反しているかどうかは、非常に主観的な質問であり、主観的な回答を受け取ります。 それが完全にどのように定義されているかと、引数がそこから直接流れることに完全に依存しています。 普遍的な定義はありません。 私の個人的な意見は、言語で許可されている場合、C コミュニティによると(カプセル化を壊さない)、またはそうであれば、C はそれを許可して非常に新しいことを実現します(そうでない場合)不可能です)。 それ以外の場合は、次のようなC ++のもう1つの誤機能です。

https://stackoverflow.com/questions/5637679/default-argument-in-the-middle-of-parameter-list [パラメータリストの中央のデフォルト引数?]

2


タイトルとURLをコピーしました