2016-09-26 11 views
2

これまでは、型情報を定数にするために基本クラスを使用しました(traitsクラスやおそらくios_baseに似ています)。これらのクラスは通常データを持たないが、一般的に使用される型(おそらく元の型を修飾する)のみを提供し、変更の際には型の定数を1つの場所で変更する。私は、そのような型クラスから継承する可能性のあるインタフェースに対して仮想継承を使用することに利点があるのか​​疑問に思っています。同様の事例のよく知られている例は、boost :: noncopyable(私はよくboost :: noncopyableをインタフェースに使用しているわけではありません)を導出できるインタフェースです。ここでタイプは基底クラス(または非コピー可能)と仮想継承を提供します

は、問題の例はほとんど例を次に示します。

#include <iostream> 
#include <memory> 


struct Path{}; 

struct SomeTypeDefs //Or something providing services similar boost::noncopyable 
{ 
    typedef std::shared_ptr<Path> PathPtr; 
}; 


struct InterfaceX : SomeTypeDefs 
{ 
    virtual PathPtr getPathX() const = 0; 
}; 

struct InterfaceY : SomeTypeDefs 
{ 
    virtual PathPtr getPathY() const = 0; 
}; 

struct Impl : InterfaceX, InterfaceY 
{ 
    private: 
     PathPtr getPathY() const override{ return PathPtr{}; } 
     PathPtr getPathX() const override{ return PathPtr{}; } 
}; 

void foo(const InterfaceX&) 
{ 
    std::cout << "foo X" << std::endl; 
} 
void foo(const InterfaceY&) 
{ 
    std::cout << "foo Y" << std::endl; 
} 

int main() 
{ 
    Impl impl; 
    foo(static_cast<InterfaceX&>(impl)); 
    foo(static_cast<InterfaceY&>(impl)); 
    return 0; 
} 

私はこのケースでは仮想継承を使用することの利点を見ることができない(いずれかがありますか)?

答えて

1

WARNING:オピニオン、おそらく直接の質問に答えていない...

は、率直に言ってこのような状況がポリシークラスではなく、継承によって処理さ良いです!例えば、私はあなたがこれを行うことができます

struct SomeTraits { 
    typedef std::shared_ptr<Path> PathPtr; 
}; 

// here class is hard-wired to policy 
struct InterfaceX 
{ 
    virtual SomeTraits::PathPtr getPathX() const = 0; 
}; 

struct InterfaceY 
{ 
    virtual SomeTraits::PathPtr getPathY() const = 0; 
}; 

を持っているでしょう

:あなたのたくさんの可能性を与える

// here class doesn't really care about specific policy... 
template <typename Traits> 
struct InterfaceX 
{ 
    typedef typename Traits:: PathPtr; 
    virtual PathPtr getPathX() const = 0; 
}; 

template <typename Traits> 
struct InterfaceY 
{ 
    typedef typename Traits:: PathPtr; 
    virtual Traits getPathY() const = 0; 
}; 

(ポリシーベースの設計を参照してください。)私はそれが率直にたくさんだと思います継承よりもきれいで、特に定義している場合タイプ

+0

したがって、ios_baseから派生したときに行われるのと同様に、パブリック継承によって多くの名前(型の)をスコープに取り込むことは悪い習慣とみなされます(ただし、州だけでなく)?このようにして、特定のコンテキストで各名前を修飾する必要はなく、すべての名前が修飾されないようにする必要があります。 OTOHおそらく、インターフェイスはios_baseほど太ってはいけません(多くの型を型定義しています...)。 1つまたは2つのタイプを引き出すには、この方法で問題はありません。 –

+0

正に言えば、タイプを取り込むだけの場合は、それを無意味に濫用することです。私は 'ios_base'は型よりも多くを定義していると思います。そのような特性クラスで型を集めて、ポリシーベースの設計を採用することは、モデル内で"ポリシー "を切り替えるのが比較的簡単になります。引数に 'PathPtr'を' unique_ptr'として言ってみましょう。あなたは2つのサイドバイサイドを持つことはできません。それはただ1つのモデルです。それはあなたのために働くかもしれませんが、それでも私は継承を避け、 fqnを避けるためにトップで '使用する '。 – Nim

関連する問題