これまでは、型情報を定数にするために基本クラスを使用しました(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;
}
私はこのケースでは仮想継承を使用することの利点を見ることができない(いずれかがありますか)?
したがって、ios_baseから派生したときに行われるのと同様に、パブリック継承によって多くの名前(型の)をスコープに取り込むことは悪い習慣とみなされます(ただし、州だけでなく)?このようにして、特定のコンテキストで各名前を修飾する必要はなく、すべての名前が修飾されないようにする必要があります。 OTOHおそらく、インターフェイスはios_baseほど太ってはいけません(多くの型を型定義しています...)。 1つまたは2つのタイプを引き出すには、この方法で問題はありません。 –
正に言えば、タイプを取り込むだけの場合は、それを無意味に濫用することです。私は 'ios_base'は型よりも多くを定義していると思います。そのような特性クラスで型を集めて、ポリシーベースの設計を採用することは、モデル内で"ポリシー "を切り替えるのが比較的簡単になります。引数に 'PathPtr'を' unique_ptr'として言ってみましょう。あなたは2つのサイドバイサイドを持つことはできません。それはただ1つのモデルです。それはあなたのために働くかもしれませんが、それでも私は継承を避け、 fqnを避けるためにトップで '使用する '。 – Nim