2014-10-13 170 views
0

我正在完成與矩陣乘法有關的任務。我們收到了一些我已經填寫的骨架文件;但是我處理一個模棱兩可的構造錯誤,構造一定要留下它是分級的方式是相同的:模糊重載構造函數:C++

TEST.CPP:6:7錯誤:重載'MAT4()的調用不明確

在我的測試代碼,我想

Mat4 I; // to result in a call to SetIdentity() via the default constructor 
I.Print("I = "); // should print the Identity Matrix for a 4x4 

相關Mat4.h代碼:

class Mat4{ 
protected: 
    float m[4][4]; 

public: 
    // ** 3A: ** 
Mat4(); 
Mat4(float=0, float=0, float=0, float=0, float=0, float=0, float=0, float=0, float=0, float=0, float=0, float=0, float=0, float=0, float=0, float=0); 

而且我Mat4.cpp代碼:

Mat4::Mat4(){ 
SetIdentity(); 
} 

Mat4::Mat4(float a, float b, float c, float d, float e, float f, float g, float h, float i, float j, float k, float l, float n, float o, float p, float q){ 
m[0][0] = a; 
m[0][1] = b; 
m[0][2] = c; 
m[0][3] = d; 
m[1][0] = e; 
m[1][1] = f; 
m[1][2] = g; 
m[1][3] = h; 
m[2][0] = i; 
m[2][1] = j; 
m[2][2] = k; 
m[2][3] = l; 
m[3][0] = n; 
m[3][1] = o; 
m[3][2] = p; 
m[3][3] = q; 
} 

一個例子使用非默認的構造函數:

Mat4 
Mat4::operator*(Mat4& that){ 
// "this" is a pointer to this class's mat4 (this->name) 
// "that" is a reference to the other matrix (that.name) 

Mat4 result(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 
int i, j, k; 
for(i = 0; i < 4; i++){ 
    for(j = 0; j < 4; j++){ 
     for(k = 0; k < 4; k++){ 
      result.m[i][j] += (float)(this->m[i][k]*that.m[k][j]); 
     } 
    } 
} 
return result; 
} 

謝謝您的幫助!

+0

編譯器應該知道,如果你想調用沒有參數或所有默認參數的「Mat4」?你需要移除默認的構造函數(因此總是調用'Mat4'全零),或者讓非默認構造函數的第一個參數沒有默認值(例如:'Mat4(float,float = 0,float = 0,float = 0,float = 0,float = 0,float = 0,float = 0,float = 0,float = 0,float = 0,float = 0,float = 0,float = 0,float = 0 ,float = 0);')(注意第一個float沒有默認參數) –

+0

第二個選項有效,非常有幫助,謝謝!我曾經認爲編譯器會意識到'Mat4'是否被賦予選項,刪除非默認值解決了我的問題。 –

+1

@Steve Lorimer:在C++術語中,*這些構造函數都是* default *構造函數。這實際上是造成歧義的原因:OP聲明瞭一個具有兩個默認構造函數的類,編譯器不知道使用哪一個。你的第二個選項建議將一個默認構造函數轉換爲非默認構造函數。 – AnT

回答

1

編譯器無法區分無參數的構造函數Mat4();從構造函數與所有默認參數Mat4(float=0,float=0...)
按照您定義它們的方式,您在調用Mat4()時需要調用什麼構造函數是模糊的。

天真的解決方案:
1.你可以虛擬參數添加到您的MAT4(),像MAT4(布爾B)來解決歧義 或
2.第一個參數的構造函數,你有許多參數默認非

所有這些解決方案處理問題,但不處理該問題的原因。
問題的原因是方法設計中的錯誤。

更新(建議的解決方案 - 變化的方法設計):根據需要
這種錯誤顯示的類中的方法設計不好。
從而@sth建議,使用一個構造函數,而不是模棱兩可2.
所有需要的情況下可以在構造函數體進行處理,所以我們得到:

Matrix(float[] arr = 0, int sizeOfArray = 0) 
{ 
    if (arr == 0) 
    // use scenario which you used for Matrix() 
    else // use scenario which you used for Matrix(float,float...) 
} 

第二個變體,而不是將支票放入構造函數的主體中並根據您可以實現的條件選擇變體根據重載分辨率選擇
當您需要2個構造函數時:

Matrix(float[] arr, int sizeOfArray) 
Matrix() 
+0

3.也許你不需要兩個單獨的構造函數,也許你所有的默認參數就足夠了。 – sth

+0

@sth當然,這是足夠的,也應該改變簽名,而不是浮動,浮動,浮動...我會建議(浮動[],int大小) –

+0

爲什麼你建議呢? – Oktalist

0

編譯器不知道「Mat4()」或 「Mat4(float = 0,float = 0,float = 0,float = 0,float = 0,float = 0,float = 0,float = 0,float = 0,float = 0,float = 0,float = 0,float = 0,float = 0,float = 0,float = 0)當你定義「Mat4 I」時