面向对象的矩阵运算编程

c++实验4

面向对象的矩阵运算编程

#pragma once
#define _CRT_SECURE_NO_WARNINGS 
#include <iomanip> 
#include <exception>
#include <typeinfo>
#include <string.h>
template <typename T>
class MAT {
	T* const e;							//指向所有整型矩阵元素的指针
	const int r, c;							//矩阵的行r和列c大小
public:
	MAT(int r, int c);						//矩阵定义
	MAT(const MAT& a);				//深拷贝构造
	MAT(MAT&& a)noexcept;			//移动构造
	virtual ~MAT()noexcept;
	virtual T* const operator[ ](int r);//取矩阵r行的第一个元素地址,r越界抛异常
	virtual MAT operator+(const MAT& a)const;	//矩阵加法,不能加抛异常
	virtual MAT operator-(const MAT& a)const;	//矩阵减法,不能减抛异常
	virtual MAT operator*(const MAT& a)const;	//矩阵乘法,不能乘抛异常
	virtual MAT operator~()const;					//矩阵转置
	virtual MAT& operator=(const MAT& a);		//深拷贝赋值运算
	virtual MAT& operator=(MAT&& a)noexcept;	//移动赋值运算
	virtual MAT& operator+=(const MAT& a);		//“+=”运算
	virtual MAT& operator-=(const MAT& a);		//“-=”运算
	virtual MAT& operator*=(const MAT& a);		//“*=”运算
//print输出至s并返回s:列用空格隔开,行用回车结束
	virtual char* print(char* s)const noexcept;
};

template <typename T>
MAT<T>::MAT(int r, int c) :r(r), c(c), e(nullptr) {
	(T*&)e = new T[r * c];
}

template <typename T>
MAT<T>::MAT(const MAT& a) : r(a.r), c(a.c),e(nullptr) {
	//if (*this == a) {
	//	throw"错误";
	//	return;
	//}
	(T*&)e = new T[r * c];
	//不要在参数表中分配内存,要首先保证之前的指针是空指针
	for (int i = 0; i < r; i++) {
		for (int j = 0; j < c; j++) {
			this->e[i * c + j] = a.e[i * c + j];
		}//深拷贝赋值
	}
}

template<typename T>
MAT<T>::MAT(MAT&& a)noexcept :r(a.r), c(a.c), e() {
	
	(T*&)e = a.e;//移动赋值
	//析构a
	(T*&)a.e = nullptr;
	(int&)a.r = 0;
	(int&)a.c = 0;
}

template<typename T>
MAT<T>::~MAT()noexcept {
	//printf("析构函数被调用\n");
	if (this->e!=nullptr)delete[]e;
	(T*&)e = nullptr;
	//只需要显式写出new分配的内存
}

template<typename T>
T* const MAT<T>::operator[](int r) {
	if (r >= this->r) {
		throw"数组越界";
		return nullptr;
	}
	return &(e[r * c]);//返回第r行第一个元素地址
}

template<typename T>
MAT<T> MAT<T>::operator+(const MAT& a)const {
	//矩阵加法要保证行列相等才能相加
	//printf("矩阵加法被调用\n");
	if (a.r != r || a.c != c) {
		throw"error";
		return *this;
	}
	MAT<T> temp(r, c);
	for (int i = 0; i < r; i++) {
		for (int j = 0; j < c; j++) {
			temp[i][j] = e[i * c + j] + a.e[i * c + j];
		}
	}
	//printf("+被调用\n");
	return temp;
}

template<typename T>
MAT<T> MAT<T>::operator-(const MAT& a)const {
	//矩阵减法要保证行列相等才能相加
	//printf("矩阵减法被调用\n");
	if (a.r != r || a.c != c) {
		throw"error";
		return *this;
	}
	MAT<T> temp(r, c);
	for (int i = 0; i < r; i++) {
		for (int j = 0; j < c; j++) {
			temp[i][j] = e[i * c + j] - a.e[i * c + j];
		}
	}
	//printf("-被调用\n");
	return temp;
}

template<typename T>
MAT<T> MAT<T>::operator*(const MAT& a)const {
	//printf("矩阵乘法被调用\n");
	//printf("a:\n");
	/*for (int i = 0; i < a.r; i++) {
		for (int j = 0; j < a.c; j++) {
			printf("%d,", a.e[i * c + j]);
		}
		printf("\n");
	}
	printf("this:\n");
	for (int i = 0; i < this->r; i++) {
		for (int j = 0; j < this->c; j++) {
			printf("%d,", this->e[i * c + j]);
		}
		printf("\n");
	}*/
	//if (a.r == 0 || r == 0) { return *this; }
	if (c != a.r) {
		throw"行列数不匹配,无法相乘";
		return *this;
	}
	MAT<T> temp(r, a.c);
	for (int i = 0; i < r; i++) {
		for (int j = 0; j < a.c; j++) {
			temp.e[i * a.c + j] = 0;
			for (int k = 0; k < a.c; k++) {
				temp.e[i * a.c + j] += e[i * a.c + k] * a.e[k * r + j];
			}
		}
	}
	/*printf("temp:\n");
	for (int i = 0; i < temp.r; i++) {
		for (int j = 0; j < temp.c; j++) {
			printf("%d,", temp[i][j]);
		}
		printf("\n");
	}*/
	return temp;
}

template <typename T>
MAT<T> MAT<T>::operator~()const {
	//printf("矩阵转置被调用\n");
	if (r == 0 || c == 0) {
		return *this;
	}
	MAT<T> temp(c, r);
	for (int i = 0; i < r; i++) {
		for (int j = 0; j < c; j++) {
			temp.e[j * r + i] = e[i * c + j];
		}
	}
	return temp;
}

template<typename T>
MAT<T>& MAT<T>::operator=(const MAT& a) {
	//printf("矩阵拷贝赋值被调用\n");
	if (e == a.e) {
		return *this;
	}
	if (this->e)delete[]e;
	(T*&)e = new T[r * c];
	(int&)r = a.r;
	(int&)c = a.c;
	//重新构造新的矩阵
	for (int i = 0; i < r; i++) {
		for (int j = 0; j < c; j++) {
			this->e[i * c + j] = a.e[i * c + j];
		}
	}
	return *this;
}

template<typename T>
MAT<T>& MAT<T>::operator=(MAT&& a)noexcept {
	//printf("矩阵移动赋值被调用\n");
	if (this->e == a.e) {
		return *this;
	}
	if (this->e)delete[]e;
	(int&)r = a.r;
	(int&)c = a.c;
	(T*&)e = a.e;
	//析构原始矩阵
	(T*&)a.e = nullptr;
	(int&)a.r = (int&)a.c = 0;
	return *this;
}

template<typename T>
MAT<T>& MAT<T>::operator+=(const MAT& a) {
	//矩阵加法要保证行列相等才能相加
	//printf("矩阵+=被调用\n");
	if (a.r != r || a.c != c) {
		throw"error";
		return *this;
	}
	for (int i = 0; i < r; i++) {
		for (int j = 0; j < c; j++) {
			e[i * c + j] += a.e[i * c + j];
		}
	}
	return *this;
}

template<typename T>
MAT<T>& MAT<T>::operator-=(const MAT& a) {
	//矩阵减法要保证行列相等才能相加
	//printf("矩阵-=被调用\n");
	if (a.r != r || a.c != c) {
		throw"error";
		return *this;
	}

	for (int i = 0; i < r; i++) {
		for (int j = 0; j < c; j++) {
			e[i * c + j] -= a.e[i * c + j];
		}
	}
	return *this;
}

template<typename T>
MAT<T>& MAT<T>::operator*=(const MAT& a) {
	//printf("矩阵*=被调用\n");
	if (this->c != a.r) {
		throw"行列数不匹配,无法相乘";
		return *this;
	}
	MAT<T> temp(r, a.c);
	for (int i = 0; i < r; i++) {
		for (int j = 0; j < a.c; j++) {
			temp.e[i * a.c + j] = 0;
			for (int k = 0; k < a.c; k++) {
				temp.e[i * a.c + j] += e[i * a.c + k] * a.e[k * r + j];
			}
		}
	}
	//移动赋值给this
	//printf("%d,%d\n", temp.r, a.r);
	this->operator=((MAT<T>&&)temp);
	/*if (this->e)delete[]e;
	(int&)r = a.r;
	(T*&)e = temp.e;
	//析构原始矩阵
	(T*&)temp.e = nullptr;
	(int&)temp.r = (int&)temp.c = 0;
	*/
	//printf("%d\n",a.r);
	return *this;
}

template<>
char* MAT<_int64>::print(char* s)const noexcept {
	//printf("矩阵打印被调用\n");
	for (int i = 0; i < r; i++) {
		for (int j = 0; j < c; j++) {
			if (i + j == 0)sprintf(s, "%d ", e[i * c + j]);
			else sprintf(s + strlen(s), "%d ", e[i * c + j]);
		}
		sprintf(s + strlen(s), "\n");
	}
	return s;
}

template<>
char* MAT<
	int>::print(char* s)const noexcept {
	//printf("矩阵打印被调用\n");
	for (int i = 0; i < r; i++) {
		for (int j = 0; j < c; j++) {
			if (i + j == 0)sprintf(s, "%d ", e[i * c + j]);
			else sprintf(s + strlen(s), "%d ", e[i * c + j]);
		}
		sprintf(s + strlen(s), "\n");
	}
	return s;
}

template<>
char* MAT<long>::print(char* s)const noexcept {
	//printf("矩阵打印被调用\n");

	for (int i = 0; i < r; i++) {
		for (int j = 0; j < c; j++) {
			if (i + j == 0)sprintf(s, "%f ", e[i * c + j]);
			else sprintf(s + strlen(s), "%f ", e[i * c + j]);
		}
		sprintf(s + strlen(s), "\n");
	}
	return s;
}
  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值