C++ class template example

C++ class template example

  • Here mainly refers to Essential C++the practice in the book, and made a simple implementation of the Matrix class
  • The main content involved are: class template, function template, operator overloading, friend function, etc.

Notice

  • Some operators can be implemented in multiple ways. For example +, *, can implement unary operator overloading within a class, or can implement binary operator overloading in the form of friend functions (the way used here)
  • When declaring a friend function template in a class, you need to reuse a template name, otherwise unresolved externalsan error will occur.
  • The implementation of the class template cannot be compiled separately from the specific use, so it is generally not recommended to write its declaration and implementation separately, otherwise it needs to be included when it is included #include "*.cpp". Therefore, it is recommended to write the implementation or definition outside the class definition in .h, you can refer to: https://blog.csdn.net/hemingliang1987/article/details/9473697
  • Specific precautions are also described in the program.

code

  • 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;
    }
    

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325486041&siteId=291194637