3

IStructure多くのクラスから派生した基本クラスがあります。

これらのクラスの一部は、他のクラスを「参照」IStructureします。たとえば、私のクラスには( からも派生する)class GuiButton : public IStructureのメンバーがあります。TextstringIStructure

今、私は要点をつかむことができるようにこれをキラキラと見ているだけです。を参照するテンプレート クラス 'Reference' が必要IStructureです。例えば:

class GuiButton : public IStructure {
public:
    Reference<Textstring> Text;
};

なぜ私がやらないのか不思議に思う人もいると思いますTextstring* Text。これは、これらの参照の一部が「外部」であるためです。テンプレートクラスは、 (名前など)Referenceに関する情報のみを保持します。IStructureこれらのクラスの一部は非常に大きく、そのクラス全体をインスタンス化して、Nameプロパティのみを使用し、それを使用しないことは無意味です。それは理にかなっていますか?

だから今私の質問に:

class Textstring : public IStructure;

Textstringテンプレートを使用してa を参照できます。

Reference<Textstring> Text;

問題は次のとおりです。一部のメソッドでは、「IStructure」にアップキャストする必要があります。たとえば、次のようになります。

void RegisterReference(Reference<IStructure> &reference);

だから私はこれを行うことができませんでした:

Reference<Textstring> txt("TextName");
RegisterReference(txt); // error

テンプレートにしないことでこれを解決できることはReferenceわかっていますが、参照がどのような型であるかを理解しやすく知ることができるので、本当にしたいと思っています。

これを達成するには、どのような方法がありますか?

ご協力いただきありがとうございます!

-アレックス

4

2 に答える 2

3

@dasblinkenlight が示唆するように、ライブラリ関数をテンプレート化できます。または、Referenceクラスに「分散」を追加できます。

template<typename T>
class Reference
{
    // ...
public:
    template<typename U>
    Reference(Reference<U> const & r) {
        // "copy" r into *this
    }
};

または変換演算子を使用

template<typename T>
class Reference
{
    // ...
public:
    template<typename U>
    operator Reference<U>() {
        // convert Reference<T> into Reference<U>
    }
};

このアプローチの欠点は、アップキャストが必要になるたびに実際に新しいオブジェクトを作成していることです。

編集

これを指摘してくれた Luc Danton に感謝します。私が書いたコードは、アップキャスト以上のものを処理します。利用可能な変換は何でも実行します。物事をもう少しうまく制限するには、次のようにすることができます (C++11 の場合):

template<typename T>
class Reference
{
    // ...
public:
    template<typename U,
      typename = typename std::enable_if<std::is_base_of<T, U>::value>::type>
    Reference(Reference<U> const & r) {
        // "copy" r into *this
    }
};
于 2012-09-01T01:21:05.117 に答える
2

次のように、関数を の型パラメーターでテンプレートにすることができますReference

template <typename R>
void RegisterReference(Reference<R> &r);
于 2012-09-01T01:13:34.293 に答える