2013-08-29 40 views
5

我是C++的新手,最近接受了面向對象編程的學習。我想寫我自己的 線性代數模塊處理三維向量和3x3矩陣。我試圖將一個矩陣定義爲由三個向量組成的類。使用另一個類C++構造一個類

class vector { 
    public: 
    double n1, n2, n3; 
    vector (double a, double b, double c) { 
     n1 = a; n2 = b; n3 = c; 
     } 
    }; 

class matrix { 
    public: 
     vector m1, m2, m3; 
     matrix (vector a, vector b, vector c) { 
       m1 = a; m2 = b; m3 = c; 
       } 
     }; 

但是,我得到一個編譯錯誤:

In constructor `matrix::matrix(vector, vector, vector)': 
no matching function for call to `vector::vector()' 

我猜測,該計劃犯規知道如何使用我定義的矢量類構造一個矩陣。 但我不明白爲什麼。如果有人能解釋,我會非常感激。

+1

使用,而不是在構造函數體賦予它們初始化列表。 –

+0

[構造函數中這個奇怪的冒號成員語法是什麼意思?]可能重複(http://stackoverflow.com/questions/1711990/what-is-this-weird-colon-member-syntax-in-the-constructor ) –

+2

您可能希望將您的矢量類放在名稱空間中,以防止與'std :: vector'混淆。因爲當我讀你的矩陣類時,我認真考慮你打算使用'std :: vector',但事實並非如此。 – hetepeperfan

回答

6

您需要通過成員初始化列表,您m1,m2,m3成員初始化:

matrix (const vector& a, const vector& b, const vector& c) 
: m1(a),m2(b),m3(c) 

注意以下幾點:

  • 這種形式只能通過構造函數中使用。
  • 您必須(至少在Pre-C++ 11中)使用此表單來初始化非靜態常量數據成員 數據成員。
  • 您必須使用此表格初始化參考數據成員。

此外,請注意,有std::vector,你可能需要重命名自己的矢量作廢命名衝突,你最好通過const引用傳遞vector

1

這是需要類載體的默認構造函數,一個無參數:

class vector { 
    public: 
    double n1, n2, n3; 
    vector() { // <- this one 
    n1 = 0; n2 = -1; // sample initializing code 
    }; 
    vector (double a, double b, double c) { 
     n1 = a; n2 = b; n3 = c; 
     } 
    }; 
4

這裏的爲什麼這是怎麼了?:

對象的施工發生在多個階段。對於你的矩陣類,你首先需要構造所有的成員對象,然後只有然後執行構造函數體。這裏要認識到的重要一點是,在構造函數體輸入之前,所有成員對象(在您的案例中爲m1,m2m3)必須已經構建。

的問題是,編譯器不能構建vector成員本身:它只知道了vector一個構造函數和一個需要三個double S代表建築,它沒有。正如billz的答案所建議的那樣,您可以使用初始化程序列表語法爲編譯器提供vector的缺失構造函數參數。

這是可行的,因爲初始化程序列表是在啓動的成員構建階段執行的,這個階段發生在構造函數體階段之前。

或者,爲vector提供默認構造函數,以便編譯器能夠自動構造矩陣成員而無需附加信息,正如Zac的答案所示。

0

爲什麼會得到這個錯誤的原因是:

  1. 你的矢量類沒有默認構造函數,你定義一個明確的構造函數的參數。
  2. 一個對象的數據成員將在對象構造期間但在執行構造函數中的代碼之前被初始化。

所以當編譯器想要創建矩陣對象時,需要先爲矩陣構造器的這些代碼「{m1 = a; m2 = b; m3 = c;}」構造/初始化m1/m2/m3。但是,m1/m2/m3的類沒有默認構造函數被調用。這就是爲什麼編譯器報告「在構造函數matrix::matrix(vector, vector, vector)': no matching function for call to vector :: vector()'」

解決方法是通過成員初始化列表初始化m1/m2/m3。這是有效的,因爲:

  1. 編譯器將在未定義時提供「默認拷貝構造函數」(實際上只是按位拷貝)。
  2. 這個「默認拷貝構造函數」可以通過成員初始化列表調用。
0

或使用「推薦C++ 11」的方式:

matrix (vector a, vector b, vector c) 
: m1(std::move(a)),m2(std::move(b)),m3(std::move(c)) { 
} 
相關問題