2016-11-16 4 views
6
#include <iostream> 

struct A 
{ 
    virtual void foo(){ std::cout << "A"; }; 
}; 

struct B : public A 
{ 
private: 
    void foo() override { std::cout << "B"; } 
}; 

int main() 
{ 
    A *p = new B; 
    p->foo();  // prints B 

// B b; 
// b.foo();  // error: foo is private 
    return 0; 
} 

// g++ -std=c++11 -Wall -Wextra -Wpedantic main.cpp && ./a.out 

したがって、B.foo()を多形的に呼び出すことはできますが、直接はできません。誰かがこの機能を使いたいと思うユースケースはありますか?プライベートな公開仮想メソッドの使用例はありますか?

答えて

2

メソッドを多態的に呼び出すことをやめます。つまり、スコープ解決演算子を使用してメソッドに直接アクセスすると、コードを維持するのが困難になることがあります。誰も経験豊富な実装者ではないことを知っている環境では(おそらく、大規模なコードベースに貢献する科学プログラマー)、あなたのコードを保護するパターンを導入する価値があります!

Javaは、悪いスタイルと見なして明示的に禁止しています。

+1

また、Javaでは禁止されていないものがあります。 –

5

これは、基本クラスの設計に依存します。あなたは、基本クラスに

class Stream { 
public: 
    virtual bool canSeek() = 0; 
    virtual void seek(int offset) = 0; 
}; 

注意を持っていると仮定します。この例では、基本クラスライブラリStreamクラスは本当に、このような仮想CanSeek性質を持っている.NETの世界から来ています。私は両者の正当な議論を見ることができるので、これが良いデザインかどうか議論したくない。そのような基底クラスが現実に存在すれば十分です。

さて、派生クラスは、それが技術的に必要とされているため、この派生クラスで

class SpecificStream final : Stream { 
private: 
    virtual bool canSeek() { return false; } 
    virtual void seek(int offset) { throw "no seek for you"; } 
} 

は、seekがすべてで実装されているという事実があることを指定してもよいです。しかし、このSpecificStreamを扱うコードは、このクラスでは全く機能しないことが既に分かっているので、呼び出さないでください。ベースのStreamクラスに対してコーディングする場合、canSeek()の結果をチェックし、結果が真である場合にのみseekを呼び出すことが理にかなっています。 SpecificStreamクラスに対してコーディングする場合、canSeek()を調べるのは意味がありません。その結果は静的に知られているので、seek()を呼び出すことは間違いありません。そのような呼び出しがプログラマーのエラーである場合、コンパイラーがそのような呼び出しに有用なメッセージを出すのを助けることは理にかなっています。

関連する問題