C++类模板example
- 这里主要是参考了
Essential C++
书籍中的做法,对Matrix类做了一个简单的实现 - 主要涉及的内容有:类模板、函数模板、操作运算符重载,友元函数等
注意
- 有些运算符可以有多种实现方式,比如
+
,*
,可以实现类内的一元操作符重载,也可以以友元函数的形式实现二元操作符的重载(这里采用的方式) - 在类中声明友元函数模板时,需要重新使用一个模板名,否则会出现
unresolved externals
的错误。 - 类模板的实现,脱离具体的使用是无法单独编译等,因此一般不建议将其声明和实现分开写,否则需要在include的时候
#include "*.cpp"
。因此建议将实现或者定义写在.h中类定义的外面,可以参考:https://blog.csdn.net/hemingliang1987/article/details/9473697 - 具体的注意事项在程序中也有对应的说明
代码
MyMatrix.h
#ifndef MY_MATRIX_H #define MY_MATRIX_H #include <cstdlib> #include <string> #include <iostream> #include <ostream> #include <assert.h> #include <time.h> #include <algorithm> #include <functional> #include <iterator> #include <fstream> #include <vector> #include <typeinfo> using namespace std; template<typename elemType> class MyMatrix { // 需要将单独定义友元函数的模板,直接使用elemType会出现错误 template<typename T> friend MyMatrix<T> operator+ (const MyMatrix<T>&, const MyMatrix<T>&); template<typename T> friend MyMatrix<T> operator* (const MyMatrix<T>&, const MyMatrix<T>&); public: MyMatrix(int row, int col) : _row(row), _col(col) { int size = _row*_col; _matrix = new elemType[ size ]; for (int i = 0; i < size; i++) { _matrix[i] = elemType(); } } MyMatrix(const MyMatrix<elemType>& matrix); MyMatrix<elemType>& operator=(const MyMatrix<elemType>& m1); void operator+= (const MyMatrix<elemType>&); ~MyMatrix() { delete[] _matrix; } const int rows() const { return _row; } const int cols() const { return _col; } elemType& operator() (int row, int col) { return _matrix[ row*_col + col ]; } const elemType& operator() (int row, int col) const { return _matrix[row*_col + col]; } ostream& print(ostream&) const; private: int _col; int _row; elemType* _matrix; }; ////////////////////////////// // 函数定义需要和类的定义放在一起,否则无法编译通过 ////////////////////////////// template<typename elemType> ostream& operator<<(ostream& os, const MyMatrix<elemType>& m) { return m.print(os); } template<typename elemType> ostream& MyMatrix<elemType>::print(ostream& os) const { int col = cols(); int size = col*rows(); for (int i = 0; i < size; i++) { if (i % col == 0) os << endl; os << _matrix[i] << " "; } os << endl; return os; } template<typename elemType> MyMatrix<elemType>::MyMatrix(const MyMatrix<elemType>& matrix) { _col = matrix._col; _row = matrix._row; _matrix = new elemType[_row*_col]; int num = _col*_row; for (int i = 0; i < num; i++) _matrix[i] = matrix._matrix[i]; } template<typename elemType> MyMatrix<elemType>& MyMatrix<elemType>::operator= (const MyMatrix<elemType>& matrix) { // 申请成功才会进行之前元素的删除 if (this != &matrix) { delete[]_matrix; _col = matrix._col; _row = matrix._row(); int num = _col*_row; _matrix = new elemType[_col*_row]; for (int i = 0; i < num; i++) _matrix[i] = matrix._matrix[i]; } return *this; } template<typename elemType> void MyMatrix<elemType>::operator+= (const MyMatrix<elemType>& m) { assert(_row == m.rows() && _col == m.cols()); int size = _row*_col; for (int i = 0; i < size; i++) _matrix[i] += m._matrix[i]; } template<typename elemType> MyMatrix<elemType> operator+ (const MyMatrix<elemType>& m1, const MyMatrix<elemType>& m2) { assert(m1.cols() == m2.cols() && m1.rows() == m2.rows()); MyMatrix<elemType> m(m1); m += m2; return m; } template<typename elemType> MyMatrix<elemType> operator* (const MyMatrix<elemType>& m1, const MyMatrix<elemType>& m2) { assert(m1.cols() == m2.rows()); MyMatrix<elemType> m(m1.rows(), m2.cols()); for (int i = 0; i < m.rows(); i++) { for (int j = 0; j < m.cols(); j++) { for (int k = 0; k < m1.cols(); k++) { m(i, j) += m1(i, k) * m2(k, j); } } } return m; } #endif
main.cpp
#include "MyMatrix.h" using namespace std; typedef long long ll; void testMatrix() { MyMatrix<double> m1(4,4); for (int i = 0; i < m1.rows(); i++) for (int j = 0; j < m1.cols(); j++) m1(i, j) = i*m1.cols() + j; cout << "m1" << m1; MyMatrix<double> m2(m1); cout << "m2" << m2; MyMatrix<double> m3 = m1 + m2; cout << "m3" << m3; MyMatrix<double> m4 = m3 * m2; cout << "m4" << m4; } int main() { // 按照时间来初始化种子,保证每次结果不一样 srand( (int)time(0) ); //cout << rand() << endl; testMatrix(); system("pause"); return 0; }