2

通常は .out ストリームでオブジェクトを描画する必要がありますcout。しかし、ユーザーが<<演算子 ( など) を持つ任意のストリームを入力できるようにしたいので、毎回QTextStreamである必要はありません。coutそのようなパラメータを定義する最も簡単な方法は何ですか?

だから、これは私が持っていたいものです。コンパイル可能なものです:

virtual void draw(GeneralOutStream out = std::cout)
{
    out <<  m_name << std::endl;
}

テンプレートを使用できることは知っていますが(これは私が実際に行っていることです)、テンプレートを必要としないソリューションがあることを望んでいました。ただし、テンプレート ソリューションは正常に機能するので、基本的には興味があります。

4

2 に答える 2

2

4つのアプローチが考えられます。

まず、std::ostreamあなたGeneralOutStreamの を取り、誰もがそれを継承すると仮定します。QTextStreamたぶん、それを にする方法で aをラップするものを書きstd::ostreamます。

次に、それを受け取って操作するtemplateメソッドを作成GeneralOutStream&& outします。これには、ヘッダーで実装を公開する必要があります。これをお勧めします。かなり強いですが、それは結局virtualかなり役に立たないことを意味します.

3 番目に、 withメソッドで渡されたジェネリック型を格納GeneralOutStreamするコンストラクターを使用して、クラス内でやり取りする一般的な出力ストリームの部分を公開する型消去を記述し、オブジェクトの実装内でその型を使用します。これにはランタイム オーバーヘッドがあり、記述するのは非常に難しく、無数の型全体を記述できるように処理する必要がある以外は --のパターンに似ています。templatepImplvirtualstd::functionGeneralOutStream

#3を書くとしたら、GeneralOutStreamが処理するはずtemplateの一連の型を取り、GeneralOutStreamメタプログラミングを行ってそれらのオーバーロードを正確に に公開し<<ます。オーバーロードの解決を手動で複製する必要があるため、これは非常に厄介です。

次に、サポートする「GeneralOutStream」タイプの列挙を作成します。二重ディスパッチ手法を使用して、virtualメソッド呼び出しを介してこれらの型のインスタンスへの参照を渡し、反対側でそれらを分離し、実装メソッドを呼び出しますtemplate。実装クラスが列挙全体を処理する必要があります。これは #3 よりも実装がやや簡単で、drawメソッドに渡すことができる型を制限しますが、実装内の型への完全なアクセスを許可しますclass

于 2013-06-17T15:30:31.233 に答える
0

任意のストリーム(から派生std::ostream) または演算子を持つ任意のオブジェクトのソリューションが必要ですか?<<

最初のケースでは、ストリーム オブジェクトへの参照を渡すことができます。

virtual void draw(std::ostream& out = cout) {
    out << m_name << std::endl;
}

コピーを渡すとコンパイルされません。

2 番目のケースでは、その関数を仮想メンバーとして定義したいように見えるため、主な問題はインターフェイスです。そうではなく、任意のオブジェクト (標準ostreamではなく、演算子が<<定義されているもの) のソリューションが必要な場合は、テンプレートを使用する必要があります。

于 2013-06-17T15:33:54.720 に答える