#《Essential C++》读书笔记# 第六章 以template进行编程

0
11

练习题答案

练习6.1 试改写以下类,使它成为一个class template:

class example
{
public:
    example(double min, double max);
    example(const double* array, int size);
    double& operator[](int index);
    bool operator==(const example&) const;
    bool insert(const double*, int);
    bool insert(double);
    double min() const { return _min; }
    double max() const { return _max; }
    void min(double);
    void max(double);
    int count(double value) const;

private:
    int size;
    double* parray;
    double _min;
    double _max;
};

改写后:

template <typename elemType>
class example
{
public:
    example(const elemType& min, const elemType& max);
    example(const elemType* array, int size);
    elemType& operator[](int index);
    bool operator==(const example&) const;
    bool insert(const elemType*, int);
    bool insert(const elemType&);
    elemType min() const { return _min; }
    elemType max() const { return _max; }
    void min(const elemType&);
    void max(const elemType&);
    int count(const elemType& value) const;

private:
    int _size;
    elemType* _parray;
    elemType _min;
    elemType _max;
};

练习6.2 重新以template形式实现练习4.3的Matrix class,并扩充其功能,使它能够通过通过heap memory(堆内存)来支持任意行列大小。分配/释放内存的操作,请在constructor/destructor中进行。

Matrix.h
#ifndef MATRIX_H 
#define MATRIX_H 
#include <iostream>
using namespace std;

template <typename elemType>
class Matrix;

template <typename elemType>
class Matrix
{
    friend Matrix operator+ <elemType> (const Matrix&, const Matrix&);
    template <typename elemType>
    friend Matrix<elemType> operator*  (const Matrix<elemType>&, const Matrix<elemType>&);

public:
    Matrix(int rows, int columns);
    Matrix(const Matrix&);
    ~Matrix() { delete[] _matrix; }
    Matrix& operator=(const Matrix&);
    void operator+= (const Matrix&);
    elemType& operator()(int row, int column)
    {
        return _matrix[row * cols() + column];
    }
    
    const elemType& operator()(int row, int column) const
    {
        return _matrix[row * cols() + column];
    }

    int rows() const { return _rows; }
    int cols() const { return _cols; }

    bool same_size(const Matrix& m) const
    {
        return rows() == m.rows() && cols() == m.cols();
    }

    bool comfortable(const Matrix& m) const
    {
        return (cols() == m.rows());
    }

    ostream& print(ostream&) const;

protected:
    int _rows;
    int _cols;
    elemType* _matrix;
};

template <typename elemType>
inline ostream& operator<<(ostream& os, const Matrix<elemType>& m)
{
    return m.print(os);
}



template<typename elemType>
Matrix<elemType> operator+(const Matrix<elemType>& m1, const Matrix<elemType>& m2)
{
    //确定m1和m2大小相同
    Matrix<elemType> result(m1);
    result += m2;
    return result;
}

template<typename elemType>
Matrix<elemType> operator * (const Matrix<elemType>& m1, const Matrix<elemType>& m2)
{
    //m1的行数(row)必须等于m2的列数(column)
    Matrix<elemType> result(m1.rows(), m2.cols());
    for (int ix = 0;ix < m1.rows();++ix)
    {
        for (int jx = 0;jx < m1.cols();++jx)
        {
            result(ix, jx) = 0;
            for (int kx = 0;kx < m1.cols();++kx)
            {
                result(ix, jx) += m1(ix, kx) * m2(kx, jx);
            }
        }
    }
    return result;
}

template <typename elemType>
void Matrix<elemType>::operator+=(const Matrix& m)
{
    //确定m1和m2的大小相同
    int matrix_size = cols() * rows();
    for (int ix = 0;ix < matrix_size;++ix)
    {
        (*(_matrix + ix)) += (*(m._matrix + ix));
    }
}

template <typename elemType>
ostream& Matrix<elemType> ::print(ostream& os) const
{
    int col = cols();
    int matrix_size = col * rows();
    for (int ix = 0;ix < matrix_size;++ix)
    {
        if (ix % col == 0)
            os << endl;
        os << (*(_matrix + ix)) << ' ';
    }
    os << endl;
    return os;
}

template <typename elemType>
Matrix<elemType>& Matrix<elemType>::operator=(const Matrix& rhs)
{
    if (this != &rhs)
    {
        _rows = rhs._rows;
        _cols = rhs._cols;
        int mat_size = _rows * _cols;
        delete[] _matrix;
        _matrix = new elemType[mat_size];
        for (int ix = 0;ix < mat_size;++ix)
            _matrix[ix] = rhs._matrix[ix];
    }
    return *this;
}


template <typename elemType>
Matrix<elemType>::Matrix(int rows, int columns) :_rows(rows), _cols(columns)
{
    int size = _rows * _cols;
    _matrix = new elemType[size];
    for (int ix = 0;ix < size;++ix)
        _matrix[ix] = elemType();
}

template <typename elemType>
Matrix<elemType>::Matrix(const Matrix& rhs)
{
    _rows = rhs._rows;
    _cols = rhs._cols;
    int mat_size = _rows * _cols;
    _matrix = new elemType[mat_size];
    for (int ix = 0;ix < mat_size;++ix)
        _matrix[ix] = rhs._matrix[ix];
}

#endif 

main.cpp

#include "Matrix.h"
#include <fstream>

int main()
{
    ofstream log("log.txt");
    if (!log)
    {
        cerr << "can't open log file!\n";
        return 0;
    }

    Matrix<float> identity(4, 4);
    log << "identity: " << identity << endl;
    float ar[16] = { 1.,0.,0.,0.,0.,1.,0.,0.,
                0.,0.,1.,0.,0.,0.,0.,1. };

    for (int i = 0, k = 0;i < 4;++i)
    {
        for (int j = 0;j < 4;++j)
            identity(i, j) = ar[k++];
    }
    log << "identity after set: " << identity << endl;

    Matrix<float> m(identity);
    log << "m: memberwise initialized: " << m << endl;

    Matrix<float> m2(8, 12);
    log << "m2: 8*12: " << m2 << endl;
    m2 = m;
    log << "m2 after memberwise assigned to m: "
        << m2 << endl;

    float ar2[16] = { 1.3,0.4,2.6,8.2,6.2,1.7,1.3,8.3,
                4.2,7.4,2.7,1.9,6.3,8.1,5.6,6.6 };

    Matrix<float> m3(4, 4);
    for (int ix = 0, kx = 0;ix < 4;++ix)
        for (int j = 0;j < 4;++j)
            m3(ix, j) = ar2[kx++];

    log << "m3: assigned random values: " << m3 << endl;

    Matrix<float> m4 = m3 * identity;
    log << m4 << endl;
    Matrix<float> m5 = m3 + m4;
    log << m5 << endl;

    m3 += m4;
    log << m3 << endl;

    return 0;
}

感谢https://www.cnblogs.com/lv-anchoret/p/8342842.html、https://blog.csdn.net/mind_v/article/details/70228402 给出的友元重载解决方法。

end。

“巅峰诞生虚伪的拥趸,黄昏见证虔诚的信徒。”

<

发布回复

请输入评论!
请输入你的名字