目录
6.1
C++代码:
//example.h
#ifndef _EXAMPLE_H_
#define _EXAMPLE_H_
#pragma once
template<typename valType>
class example
{
private:
int size;
valType* parray;
valType _min;
valType _max;
public:
example(valType &min, valType &max);
example(const valType* array, int size);
valType& operator[](int index);
bool operator==(const example& ex)const;
bool insert(const valType* val, int a);
bool insert(valType &val);
valType min()const {return _min;}
valType max()const {return _max;}
void min(valType& val);
void max(valType& val);
int count(valType& val)const;
};
因为valType现在可能被用来表示内置类型或class类,因此以传址(by reference)方式而非传值(by value)方式传递比较好。
6.2
C++代码:
//Matrix.h
#ifndef _MATRIX_H_
#define _MATRIX_H_
#include<iostream>
using namespace std;
#pragma once
template<typename elemType>
class Matrix
{
private:
elemType*_Mat; //动态分配内存
int _rows;
int _cols;
public:
//构造函数:
Matrix(int rows, int columns);
//重载复制构造函数(深度复制)
Matrix(const Matrix&);
//使用动态内存分配,需要显式的定义析构函数
~Matrix();
//重载赋值运算符(深度复制-先分配内存在复制数据)
Matrix& operator=(const Matrix& M1);
//矩阵加法:
friend Matrix operator+(Matrix& M1, Matrix& M2);
//矩阵乘法:
friend Matrix operator*(Matrix& M1, Matrix& M2);
//打印矩阵内容函数print()
void print();
//复合运算符+=
void operator+=(Matrix M1);
//function call运算符(返回参数对应位置矩阵的元素值)
elemType& operator()(int row, int column){return _Mat[row][column];}
elemType operator()(int row, int column) const{return _Mat[row][column];}
//输出
friend ostream& operator<<(ostream& os, const Matrix M1);
int cols(){return _cols;}
int rows(){return _rows;}
bool same_size(const Matrix& m)const { return rows() == m.rows() && cols() == m.cols(); }
bool comfortable(const Matrix&m)const{return (cols()==m._rows()) }
};
#endif
//Matrix.cpp
#include"Matrix.h"
//构造函数:
//constructor
template<typename elemType>
Matrix<elemType>::Matrix(int rows,int columns)
{
_rows = rows;
_cols = columns;
int mat_size = _rows * _cols;
_Mat = new elemType[mat_size];
}
//重载复制构造函数
template<typename elemType>
Matrix<elemType>::Matrix(const Matrix& rhs)
{
_rows = rhs._rows;
_cols = rhs._cols;
int mat_size = _rows * _cols;
_Mat = new elemType[mat_size];
for (int i = 0; i < mat_size; i++)
{
_Mat[i] = rhs._Mat[i];
}
}
//重载赋值运算符
template<typename elemType>
Matrix<elemType>& Matrix<elemType>::operator=(const Matrix& rhs)
{
if (this != rhs)
{
_rows = rhs._rows;
_colhs = rhs._cols;
int mat_size = _rows * _clos;
//相较于复制构造函数的深度复制(多应用于还未初始化的对象),重载赋值运算符多应用于已经初始化过的对象,所以要多一步delete之前的内存,防止内存浪费。
delete[]_Mat;
_Mat = new elemType[mat_size];
for (int i = 0; i < mat_size; i++)
{
_Mat[i] = rhs._Mat[i];
}
}
return *this;
}
//定义析构函数
template<typename elemType>
Matrix<elemType>::~Matrix()
{
delete[] _Mat;
}
//友元函数无需声明所属类
//友元函数可以直接访问类中的私有数据
//复合运算符+=
template<typename elemType>
void Matrix<elemType>::operator+=(Matrix<elemType> M1)
{
int mat_size = _rows * _cols;
for (int i = 0; i < mat_size; i++)
{
(*(_Mat + i)) += (*(m._Mat + i)); //_Mat[i] += m._Mat[i];
}
}
//矩阵加法:
template<typename elemType>
Matrix<elemType> operator+(Matrix<elemType>& M1, Matrix<elemType>& M2)
{
Matrix<elemType>result(M1);
result += m2; //利用了重载的+=运算符
return result;
}
//矩阵乘法:
template<typename elemType>
Matrix<elemType> operator*(Matrix<elemType>& M1, Matrix<elemType>& M2)
{
//矩阵相乘的前提:M1的列数等于M2的行数,相乘得出的行列为:M1.rows x M2.cols;(M1的行数 X M2的列数)
Matrix<elemType> result(m1._rows, m2._cols);
for (int i = 0; i < m1._rows; i++) //行遍历
{
for (int j = 0; j < m1._cols; j++) //列遍历
{
for (int x = 0; x < m1._cols; x++)
{
//运算符 () 的重载, result(i,j) 即为 result._Mat[i][j]
result(i, j) += M1(i, x) * M2(x, j); //M1的行元素依次乘以M2的列元素
}
}
}
return result;
}
//打印矩阵内容函数print()
template<typename elemType>
void Matrix<elemType>::print()
{
int mat_size = _rows * _cols;
for (int i = 0; i < mat_size; i++)
{
if (i % _cols == 0)
{
os << endl;
}
os << _Mat[i] << " ";
}
os << endl;
}
//输出
template<typename elemType>
ostream& operator<<(ostream& os, const Matrix<elemType> M1)
{
M1.print();
return os;
}
1.在类中进行动态分配内存则需要重载复制构造函数和赋值运算符:
重载复制构造函数:
//重载复制构造函数
template<typename elemType>
Matrix<elemType>::Matrix(const Matrix& rhs)
{
_rows = rhs._rows;
_cols = rhs._cols;
int mat_size = _rows * _cols;
_Mat = new elemType[mat_size];
for (int i = 0; i < mat_size; i++)
{
_Mat[i] = rhs._Mat[i];
}
}
重载赋值运算符:
//重载赋值运算符
template<typename elemType>
Matrix<elemType>& Matrix<elemType>::operator=(const Matrix& rhs)
{
if (this != rhs)
{
_rows = rhs._rows;
_colhs = rhs._cols;
int mat_size = _rows * _clos;
//相较于复制构造函数的深度复制(多应用于还未初始化的对象),重载赋值运算符多应用于已经初始化过的对象,所以要多一步delete之前的内存,防止内存浪费。
delete[]_Mat;
_Mat = new elemType[mat_size];
for (int i = 0; i < mat_size; i++)
{
_Mat[i] = rhs._Mat[i];
}
}
return *this;
}
其中复制构造函数大多作用于未初始化的对象,而赋值运算符大多作用于已经初始化的对象,所以相较于复制构造函数的深度复制,多出一段delete用于删除之前的内存,再进行内存的分配和数据的复制。
2.在类中进行动态分配内存则一定需要显式的定义析构函数来完成内存的释放:
//定义析构函数
template<typename elemType>
Matrix<elemType>::~Matrix()
{
delete[] _Mat;
}
3.模板类无法为每一个元素明确初值,因为模板参数elemType所代表的实际类型可能有很多种,因此模板类只允许我们以default constructor(默认构造函数)的形式来指定初值。