泛型矩陣類

2021-08-29 03:39:03 字數 4853 閱讀 3833

矩陣就不用再解釋了,寫成泛型主要是為了幾個方便:

1、方便在棧上分配空間。由於維度在編譯期已知,所以可以做到在棧上分配空間。當然如果這個物件是new出來的,自然是在堆上分配,這裡說的是在棧上分配這個物件時,矩陣元素所占用的空間也在棧上分配。

2、方便在編譯期檢查非法的矩陣運算。c++模板的強大推導能力可以在編譯期推導出結果矩陣的維度。

3、泛型類在方法內聯上具有優勢。

這個矩陣類為了能夠直接從陣列賦值,使用了乙個arrayporxy類(可參考《imperfect c++》)。

**如下:

template 

<

class

t, int

d1, 

intd2=1

>

class

arrayproxy

arrayproxy(t (

&value)[d1

*d2])

: data(value)t*

getdata() 

const};

這個只是簡單的實現。

因為我基本上不使用這個矩陣類,所以只完成幾個簡單功能:

1、從陣列賦值:

int a[3] = , };

matrixm1(a); 或

int a = ;

matrixm1(a);

matrixm2(a);

matrixm3(a);

matrixm4(a);

2、矩陣乘法:

matrixm1;

matrixm2;

// m1 * m2  <== 編譯錯誤,維度不匹配

matrixm3;

matrixm4 = m1 * m3; // <== 合法

// m3 * m1; // <== 編譯錯誤,維度不匹配

原始碼如下:

template 

<

class

t, int

r, int

c>

class

matrix

matrix(

const

matrix

&rhs)

matrix

&operator=(

const

matrix

&rhs)

public

:matrix(

const

arrayproxy

<

t,r,c

>&

arr)

~matrix(

void

)public:t 

get(

intr, 

intc) 

const

void

set(

intr, 

intc, t v)

intgetcols () 

const

intgetrows () 

const

bool

operator==(

const

matrix

&rhs) const

bool

operator!=(

const

matrix

&rhs) const

};template 

<

class

t, int

r, int

c, int

c1>

matrix

<

t,r,c1

>

operator*(

const

matrix

<

t,r,c

>&

lhs, 

const

matrix

<

t,c,c1

>&

rhs)

result.

set(r,c,value);}}

return

result;}

測試**:

intmain()

inta =;

matrix

<

int, 3, 

4>

m5(a);

intb[3][

4] =,

,};matrix

<

int, 3, 

4>

m6(b);

matrix

<

int, 3, 

4>

m7(m5);

matrix

<

int, 3, 

4>

m8 =

m5;matrix

<

int, 3, 

4>

m9;m9 

=m5;

for(

inti=0

; i<

3; i++)

for(

intj=0

; j<

4; j++)

//維數不匹配,編譯錯誤

//matrixm10 = m9;

intc[2] 

=, };

//陣列大小不匹配,編譯錯誤

//matrixm10(c);

intd =;

//陣列大小不匹配,編譯錯誤

//matrixm11(d);

//乘法維數不合適,無法相乘

//m1 * m2;

matrix

<

int,4,

3>

m12;

//匹配,可以相乘

matrix

<

int, 3, 

3>

m13 

=m1 

*m12;

matrix

<

int, 8, 

3>

m14;

//無法相乘

//matrixm15 = m1 * m14;

//可以相乘

matrix

<

int, 8, 

4>

m15 

=m14 

*m1;

}, };

matrix

<

int, 2, 

5>

m1(a);

intb[5][

3] =, , , , };

matrix

<

int, 5, 

3>

m2(b);

intc[2][

3] =, };

matrix

<

int, 2, 

3>

m3(c);

matrix

<

int, 2, 

3>

m4 =

m1 *

m2;assert(m4 

==m3);

cout 

<<

m4.get(0

,0) <<

endl;

}return0;

} 補充:

1、加法、減法只需要2個矩陣維度相同即可。

template 

<

class

t, class

r, class

c>

matrix

<

t,r,c

>

operator+(

const

matrix

<

t,r,c

>&

lhs, 

const

matrix

<

t,r,c

>&

rhs)

2、由於1x1的矩陣可以看成乙個標量,矩陣與標量運算結果維數與原矩陣相同,可以過載來實現。

template 

<

class

t, class

r, class

c>

matrix

<

t,r,c

>

operator*(

const

matrix

<

t,r,c

>&

lhs, 

const

matrix

&rhs)

3、由於型別泛化,可能某些合理的運算無法進行,比如float型矩陣,與乙個int型標量運算等。這些最好是借助型別萃取等手段,推導出運算以後的型別。(c++0x中包含自動獲取運算結果型別的關鍵字typeof,等幾年就可以用了:)。gcc編譯器中已有實現,不過似乎有bug)。

4、其它。泛型實現可能會有一些考慮不周的地方,強型別有強型別的好處,不過必須要有完整的泛型演算法支撐,否則難以使用。也可以把泛型矩陣類從乙個普通矩陣類派生,這樣更容易寫出通用演算法,不過在實現上可能要借助於執行期多型,對於矩陣類來說並不合適。

5、其它。。前面說c++的模板相當強大,d語言模板到目前為止似乎已經完全實現了c++模板的功能,還增加了一些比如字串值參模板等特性,比c++模板功能更多。在**編寫上,由於可以編寫靜態判斷語句(編譯期)以及靜態斷言,編寫模板比c++更容易。有時間可以試試用它寫個矩陣類,純粹是興趣,這些東西真的很難用到,現成的庫也挺多。

6、其它。。。c++0x要提供「template typedef」,也就是可以這樣定義:

template typedef matrixmatrixint;  // 定義型別,維度不定

template typedef matrixmatrix4x4; // 定義維度,型別不定

由此可以出定義行向量、列向量、標量等,當然實際使用起來可能沒那麼舒服了。

泛型 泛型類 泛型方法 泛型擦除

1 是什麼?一種允許我們在不確定引數型別時候使用的型別。例如我不知道a方法應該會傳string還是int,我就用個泛型先佔坑。2 為什麼要用泛型?泛型可以在編譯期自動確定具體型別,檢查型別是否匹配,可以提高 的重用率,減少冗餘編碼。3 泛型與object的區別?像上面說的我不知道方法a的引數型別,其...

泛型之泛型類

public class a 構造引數型別上使用泛型 public a t t 方法返回值上使用泛型 public t gett 方法的引數上使用泛型 這是泛型類的方法,而不是泛型方法 public void sett t t 方法的返回值和引數型別上使用泛型 public t foo t t pu...

泛型之泛型類

public class a 構造引數型別上使用泛型 public a t t 方法返回值上使用泛型 public t gett 方法的引數上使用泛型 這是泛型類的方法,而不是泛型方法 public void sett t t 方法的返回值和引數型別上使用泛型 public t foo t t pu...