仮想メンバーをプライベートに宣言するためのすべての呼び出しにもかかわらず、議論は単に水を保持していません。多くの場合、仮想関数の派生クラスのオーバーライドは、基本クラス バージョンを呼び出す必要があります。宣言されている場合はできませんprivate
:
class Base
{
private:
int m_data;
virtual void cleanup() { /*do something*/ }
protected:
Base(int idata): m_data (idata) {}
public:
int data() const { return m_data; }
void set_data (int ndata) { m_data = ndata; cleanup(); }
};
class Derived: public Base
{
private:
void cleanup() override
{
// do other stuff
Base::cleanup(); // nope, can't do it
}
public:
Derived (int idata): base(idata) {}
};
基本クラスのメソッドを宣言する必要がありますprotected
。
次に、コメントを介して、メソッドをオーバーライドする必要があるが呼び出さないことを示すという醜い手段を取る必要があります。
class Base
{
...
protected:
// chained virtual function!
// call in your derived version but nowhere else.
// Use set_data instead
virtual void cleanup() { /* do something */ }
...
したがって、ハーブ・サッターのガイドライン #3...しかし、いずれにせよ、馬は納屋から出ています。
何かを宣言するprotected
と、派生クラスの作成者が保護された内部構造を理解して適切に使用することを暗黙的に信頼します。これは、宣言がメンバーfriend
に対するより深い信頼を意味するのと同じです。private
その信頼に反して悪い振る舞いをするユーザー (たとえば、わざわざドキュメントを読まないことで「無知」というレッテルを貼られるなど) は、自分自身に責任があります。
更新:プライベート仮想関数を使用して、この方法で仮想関数の実装を「チェーン」できると主張するフィードバックがいくつかありました。もしそうなら、私はそれを見てみたいです。
私が使用する C++ コンパイラでは、派生クラスの実装からプライベート基本クラスの実装を呼び出すことは絶対にできません。
C++ 委員会がこの特定のアクセスを許可するために「プライベート」を緩和した場合、私はすべてプライベート仮想関数を支持します。現状では、馬が盗まれた後は納屋のドアをロックするように勧められています。