2017-05-28 45 views
3

我想創建一個類來管理矩陣,我遇到了構造函數的問題。 目標是找到調用Matrix objet的構造函數的最簡單方法,因爲它知道某些構造函數具有與保持清晰相同的頭文件。 這是我所嘗試的想法:如何在聲明/參數相同時重載構造函數/函數?

Matrix id; // create identity matrix 
Matrix scale(x, y, z); // create directly a scale matrix 
Matrix translation(x, y, z) // create a translation matrix 
... 

在這裏,所有的參數都是float其實如此我不能超載的構造,我唯一看到的是使用的模板,但只對那些特殊情況則我不知道該怎麼辦。

解決方案

最後,我決定做一個抽象類是這樣的:

class _Mat 
{ 
    public : 
     virtual ~_Mat(void) = 0; 

     // ... 
} 

class Mat : public _Mat 
{ 
    public : 
     Mat(void); 
     virtual ~Mat(void); 

     class Scale : public _Mat 
     { 
      public : 
       Scale(float x, float y, float z); 
       vitual ~Scale(void); 

       // ... 
     } 

     // ... 
} 

所有將被定義爲_Mat和其他類將只是有用的爲他們構造函數(S)

最後,我們可以調用這樣的構造函數:

Mat id; 
Mat::Scale scale(2, 2, 2); 
// ... 
+0

聽起來像是你應該看的繼承。 –

+1

但類將是相同的,它是正確的構造函數的變化,它是奇怪的創建例如「MatrixScale」,這是相同的「矩陣」只是一個不同的構造函數 – Zone31

+0

請澄清你的問題,因爲它不清楚你想要什麼。 '矩陣'和'矩陣'是不同的類型,在這裏不會發生過載。 – Logman

回答

4

您可以保持簡單並使用靜態成員函數:

struct Matrix 
{ 
    // ... 

    static Matrix Translate(float x, float y, float z) {/*...*/} 
    static Matrix Scale(float x, float y, float z) {/*...*/} 
}; 

// ... 

Matrix m = Matrix::Scale(1,2,3); 
+0

謝謝你,你給了我一個關於引用操作符的想法 – Zone31

2

您有以下選擇:

  1. 介紹的構造不同類型的不同虛擬參數的重載區分。這是hacky,我不會推薦它。

  2. 使用繼承。創建不同的子類,其中每個子類都按其構造函數提供的功能命名。

  3. 讓你的構造函數保密並引入public static工廠方法,它們有很長很長的名字,清楚地表明他們做了什麼。 (沒有超載。)

就我個人而言,我會去第三選擇。

4

您正在尋找tag分派。您可以看到它在標準庫中使用,例如在std::pair's constructor的過載中。

你只需要聲明一個「標籤」結構,這是用來指導重載解析:

struct translation_matrix_tag_t {} static translation_matrix_tag; 
struct scale_matrix_tag_t {} static scale_matrix_tag; 

再超載的構造函數:

struct Matrix { 

    Matrix(translation_matrix_tag_t, float, float, float); 
    Matrix(scale_matrix_tag_t, float, float, float); 

    // ... 
}; 

然後你可以使用它像這樣:

void foo() { 
    Matrix m1{translation_matrix_tag, x, y, z}; 
    Matrix m2{scale_matrix_tag, x, y, z}; 
} 
+0

但是我們發送一個新參數來指定我們想要使用的解決方案不是? – Zone31

+0

@ Zone31是的,這就是我們所做的。 – Quentin

+0

沒有一種方法來調用構造函數,而無需爲構造函數的主體添加無用參數? – Zone31