2013-10-05 274 views
1

我創建了一個矩陣類(主要用於自我實踐,我知道關於Eigen)。在其中,我有矩陣乘法定義爲人們所期望的 - 該方法接受對Matrix對象的const引用並返回Matrix對象。基類方法返回派生類objec

Matrix Matrix::operator *(const Matrix& rhs) const 
{ 
    Matrix temp(mRows,rhs.mCols); 
    ... //do Matrix Multiplication 
    return temp; 
} 

然後我導出一個DCM類(方向餘弦矩陣 - 只是一種特殊的矩陣)。

class DCM: public Matrix 
{ 
    .... // class definition here, but does NOT contain definition for 
     // matrix multiplication  
}; 

我可以創建兩個DCM對象並將它們放在一起沒有問題,但返回的對象類型爲Matrix。

DCM Rvb_q(q); 

DCM Rvb_p(p); 

DCM Rvb_pq(Rvb_p*Rvb_q); // error because Rvb_p*Rvb_q returns a Matrix object 

有沒有辦法讓該函數返回一個DCM對象而不必重新編寫派生類中的函數?一種方法是給這個構造添加到派生類:

DCM(const Matrix &M):Matrix(M) {} 

,但似乎真的效率不高(爲乘法創建一個新的對象,然後拷貝製作DCM對象時)和限制(每次我乘2 DCM對象一起,我必須創建一個新的DCM對象,以便將Matrix對象複製到 - 我不能僅將返回的對象用作DCM)。有沒有辦法重用基類函數,但讓它返回派生類類型?

+0

他們確實需要返回派生類型嗎?您的繼承層次結構已經暗示DCM是一個矩陣,並且規定兩者之間的乘法運算是相同的(即,它不必考慮DCM的特殊屬性),那麼返回就好了一個矩陣,儘管你可能想/需要一個轉換構造函數。 –

+0

如果您將移動構造函數添加到Matrix類中,則「DCM Rvb_pq(Rvb_p * Rvb_q)'會更有效。 –

+0

@TimoGeusch - 他們做的。我也推導出一個四元數類 - 你可以將一個DCM轉換爲四元數(我將要定義),但是通常把矩陣轉換爲四元數是沒有意義的。因此,這將允許我將兩個DCM相乘並將結果轉換爲四元數 –

回答

1

如果有的話,從矩陣相乘繼承的同類型(乘法運算下是關閉的),那麼你就可以破解一起類似:

template <class TMatrix> 
TMatrix Matrix::operator *(const TMatrix& rhs) 
{ 
    TMatrix temp(mRows, rhs.mCols); 
    // multiply 
    return temp; 
} 

但我不建議。在這樣的情況下,我認爲最好是明確的,通過一個DCM乘以DCM導致DCM:

DCM DCM::operator *(const DCM& rhs) 
{ 
    return Matrix::operator*(rhs); 
} 

在這種情況下,你也應該申報(可能是私人)DCM(const Matrix&) and DCM(Matrix&&)

+0

因此,無論是否包含DCM :: DCM運算符*(const DCM&rhs)函數定義,添加DCM(常量Matrix&)都會修復問題。由於它沒有它的工作原因,我還應該包括它嗎? 此外,我只是瞭解右值引用 - 我已經得到了移動分配的工作,但移動構造函數似乎並沒有被調用。我正在爲此單獨發佈一篇文章。 –

+0

說實話,我只是堅持使用DCM(const Matrix&)和DCM(Matrix &&)。我的方法的主要好處是如果你想說自動m ='dcm1 * dcm2'並且想要m是DCM類型的話。另外,我真的鼓勵你看看[The C++ Programming Language](http://www.stroustrup.com/4th.html)的第29章,整個章節都會討論矩陣類的設計。我還在研究這本書,所以我還沒有看到,但是看到它是由C++的創建者編寫的,它可能是一個體面的設計:) –

1

您可以使用Curiously Recurrent Template Pattern來實現。 CRTP是一個類,其中一個類從模板類繼承,並以它作爲模板參數。例如:

template<typename T> 
struct CRTP_base {}; 

struct foo : public CRTP_base<foo> {}; 

基類知道從中派生什麼類的事實,這個成語繼電器的功率。您可以使用該屬性來解決您的問題:

template<typename T> 
struct matrix_base 
{ 
    T& operator*=(const T& rhs) 
    { 
     /* Multiplication code */ 
     return static_cast<T&>(*this); 
    } 
}; 

struct DCM : public matrix_base<DCM> {}; 

int main() 
{ 
    DCM a,b c; 

    a *= b; //OK, call to matrix_base<DCM>::operator*, which expects a DCM as parameter, 
      //and returns a reference to a DCM. 
}