2012-01-27 31 views
2

我有幾個純虛類,MatrixVector的。在我的代碼庫中,我試圖只創建它們的依賴關係,而不是它們的具體子類,例如SimpleTransformationMatrix44SimpleTranslationVector4。這樣做的動機是,我可以使用第三方(適應)類來代替我的地方,沒有太多麻煩。從抽象類中聲明的重載算術運算符返回指針是否合理?

我想算術運算符(從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

第一關:重載運算符是什麼,最適用於值類型。正如你發現的那樣,多態性並不能很好地發揮它的作用。如果你願意柺杖走路,這可能會有所幫助,但:

如果您按照Stackoverflow's operator overloading FAQ的建議,您將執行operator+()作爲operator+=()上的非成員。後者返回參考。這仍然是一個問題,因爲它只能返回一個基類的引用,但只要你用它來表達期待,那就沒問題。

如果再模板化operator+()as DeadMG suggested,你也許可以做你想做的:

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

注意,這會趕上對於沒有更好的匹配operator+()過載可以找到的任何T。 (這可能看起來是一個好主意 - 直到你忘記包含頭部並且該操作符捕獲了x+y,使得代碼編譯,但是默默地產生了錯誤的結果。)所以你可能想限制這個。

一種方法是把它放到同一個命名空間,你矩陣與向量類型。或者,您使用static_assert來確保僅傳入來自兩者的類型。

+0

對於遲到的重播,我沉迷了一段時間。我不確定我是否有模板化的'operator +()'(我沒有意識到那是DeadMG所說的),因爲你說的原因。我想我只會使用常規方法而不是運算符,這樣我就不會破壞重載約定。謝謝! – 2012-03-03 22:00:53

0

有我關閉了這個想法的情節?

是的。解決此問題的適當方法是通過模板實現靈活性,而不是繼承。繼承是絕對不適合這種問題的。此外,通常(如果沒有強制)將矢量或矩陣的維度指定爲模板參數,而不是在運行時。

+0

'Matrix'和'Vector'實際上是模板,但是我留下了那些細節以使我的示例更簡單。他們將數據類型(例如float)和大小作爲模板參數。我傾向於改變'矩陣'來採取維度。我如何通過模板實現靈活性? – 2012-01-27 21:18:24