2012-01-27 4 views
2

純粋な仮想クラスをいくつか持っています。MatrixVectorです。私のコードベース全体を通して、私はそれらの依存関係を作成するだけで、具体的なサブクラスは作成しません。 SimpleTransformationMatrix44およびSimpleTranslationVector4。これの動機は、私の代わりに第三者(適応)クラスを使用することができることです。抽象クラスで宣言されたオーバーロードされた算術演算子からポインタを返すのは妥当ですか?

私は(hereから供給)算術演算子をオーバーロードしたいと思います:

T T::operator +(const T& b) const; 
T T::operator -(const T& b) const; 
T T::operator *(const T& b) const; 

私は彼らへの参照/ポインタの操作を実行するために有効であるように、純粋仮想クラスでそれらを宣言したいです問題は、抽象クラスを値で返すことができないということです。私は考えることができる最善の解決策は、このようなものである:(!ダウンキャストなし)

std::unique_ptr<T> T::operator +(const T& b) const; 
std::unique_ptr<T> T::operator -(const T& b) const; 
std::unique_ptr<T> T::operator *(const T& b) const; 

これを可能にする:

std::unique_ptr<Matrix> exampleFunction(const Matrix& matrix1, const Matrix& matrix2) 
{ 
    std::unique_ptr<Matrix> product = matrix1 * matrix2; 
    return std::move(product); 
} 

ポインタが戻って以来、この場合の唯一の選択肢であると思われます値は無効で、参照を返すのは単なる愚かです。

私の質問は次のようなものです:このアイデアでプロットを外したことはありますか?あなたが作業していたいくつかのコードでそれを見たなら、あなたは自分自身にWTFを考えているでしょうか?これを達成するより良い方法はありますか?

答えて

1

第1オフ:演算子のオーバーロードは、値型に最適なものです。あなたが知っているように、多型はそれでうまくいきません。しかし、松葉杖を歩きたい場合は、これが助けになるかもしれません。

Stackoverflow's operator overloading FAQのアドバイスに従うと、operator+()operator+=()の非会員として実装されます。後者は参照を返します。それは基本クラス参照のみを返すことができるので、それでも問題はありますが、それを期待する式のために使用する限り、あなたはうまくいきます。

あなたその後、テンプレート化operator+()as DeadMG suggested場合は、あなたがやりたいことができるかもしれない:これは無より良いマッチングoperator+()過負荷を見つけることができるためにあらゆるTをキャッチすることを

template<typename T> 
T operator+(const T lhs, const T& rhs) 
{ 
    lhs += rhs; 
    return lhs; 
} 

は注意してください。 (これはよい考えのように思えるかもしれません - ヘッダーを含めるのを忘れるまで、この演算子はx+yを捕まえてコードをコンパイルしますが、間違った結果を招くことがあります)。

1つの方法は、行列とベクトル型と同じ名前空間に配置することです。または、static_assertを使用して、2つの型から派生した型だけが渡されるようにします。

+0

遅刻して申し訳ありませんが、私はこれをしばらく思っていました。あなたが述べた理由のためにテンプレートの 'operator +()'(DeadMGが言っていたことはわかりませんでした)が好きです。私は、演算子の代わりに通常のメソッドを使用して、オーバーロードの規則を破らないようにすると思います。ありがとう! –

0

私はこのアイデアでプロットを外しましたか?

はい。この問題に対する適切な解決策は、継承ではなくテンプレートを使用して柔軟性を実装することです。継承は、この種の問題に最も適していません。さらに、実行時ではなく、テンプレートパラメータとして指定されたベクトルまたは行列の次元を追加するのが普通です(必須ではない場合)。

+0

'Matrix'と' Vector'は実際にはテンプレートですが、私はもっと簡単にするためにその詳細を残しました。彼らはデータ型(例えばfloat)とサイズをテンプレート引数として取ります。私はディメンションを取るために「マトリックス」を変えることに傾いていました。テンプレートを使って柔軟性を実装するにはどうすればよいですか? –

関連する問題