用vector容器完成向量类的重载
题目要求
题目描述
实现一个向量类,在类中,分别重载 “+, -, *(数乘,矩阵乘) ” 基本运算以及 “==,!=,-(负号), =(赋值)" 操作符,以实现向量基本运算。
要求:
- 除了重载相应的操作符,也需要实现一个类的一些基本的方法(接口),比如构造、析构、拷贝构造等。
- 可以使用C++标准模板库(STL)里面的vector类,也可以使用你前一次作业实现的动态数组作为你这次所要实现的向量类的基础。
提示:
- 此次会提供一份测试代码(非线上测试代码)
- 该测试用例中涉及的Vecto自行设计,逐渐熟悉并掌握类接口设计能力
- 建议可以先注释掉全部或大部分测试代码,从而以免在一开始因代码仅完成很少部分,产生太多编译错误
- 仅通过测试代码分析类的职责,开发完成后,放开测试代码
- 测试不通过,再考虑职责分析是否有误解
- 建议思考的方式为“我应该为Vector提供什么接口,这些接口应当完成什么功能以满足他们的职责”为出发点,实现后通过测试用例验证
- 而非“我应该为Vector提供什么接口,以能通过测试代码”为出发点,通不过一句,改一个函数,通过一句,就转移到下一个函数的方式
- 前者以对象为中心,考虑职责,在思考过程和实现过程中,类独立设计并实现,最终通过交互完成功能,类设计和实现的过程和测试代码的顺序无关,
- 仅与自身从测试代码中分析并融合出的职责需求有关
- 后者以过程为中心,考虑功能,思考过程和实现的过程中,类在不断的“测试过程”中运行,以测试代码运行的顺序增加功能
代码为
/*向量类的重载运算
* by——keli
*2020.12.12
*/
#include<stdio.h>
#include<assert.h>
#include<iostream>
#include<vector>
#include<string.h>
using namespace std;
class Vector
{
public:
//typedef std::vector<double> Data;
static Vector INVALID_VECTOR;
public:
//无参数构造函数
Vector();
//长度和一个数组为参数的构造函数
Vector(int length, const double data[]);
//参数为长度和一个double数的构造函数
Vector(int length, const double data);
//析构函数
~Vector();
public:
//返回向量元素个数
int size();
//重载[]
double operator[](int index);
//重载+
Vector operator+(const Vector& temp);
//重载-
Vector operator-(const Vector& temp);
//重载*
Vector operator*(const double a);
//重载==
bool operator==(const Vector& temp);
//重载!=
bool operator!=(const Vector& temp);
//重载负号
Vector operator-();
//重载=double
Vector operator=(const double element);
//重载+double,每个元素都加一个数
Vector operator+(const double element);
//重载-double,每个元素都减一个数
Vector operator-(const double element);
private:
//重载<<
friend std::ostream& operator<<(std::ostream& os, const Vector& vector);
private:
//数据,向量p
vector<double>p;
};
Vector::Vector()
{
p.clear();
}
Vector::Vector(int length, const double data[])
{
//这里的初始化和容器插入不同,必须先把容器归零
p.clear();
for (int i = 0; i < length; i++)
{//把data[]的数据放入vector
p.push_back(data[i]);
}
}
Vector::Vector(int length, const double data)
{
p.clear();
for (int i = 0; i < length; i++)
{
p.push_back(data);
}//length个数据初始为data
}
Vector::~Vector()
{
p.clear();//清理内存
}
int Vector::size()
{
//vector内置函数size,返回容器元素个数
return p.size();
}
double Vector::operator[](int index)
{
//随机访问容器元素
return p.at(index);
}
Vector Vector::operator+(const Vector& temp)
{
if (p.size() != temp.p.size())//容量不相等时
{
return Vector::INVALID_VECTOR;//返回非法向量
}
Vector sum;//和向量
for (int i = 0; i < p.size(); i++)
{
sum.p.push_back(p.at(i) + temp.p.at(i));
}
return sum;
}
Vector Vector::operator-(const Vector& temp)
{
if (p.size() != temp.p.size())//容量不相等时
{
return Vector::INVALID_VECTOR;//返回非法向量
}
Vector difference;//差向量
for (int i = 0; i < p.size(); i++)
{
difference.p.push_back(p.at(i) - temp.p.at(i));
}
return difference;
}
Vector Vector::operator*(const double a)
{
Vector product;//积向量
for (int i = 0; i < p.size(); i++)
{
product.p.push_back(p.at(i)*a);
}
return product;
}
bool Vector::operator==(const Vector& temp)
{
return (this->p == temp.p);
}
bool Vector::operator!=(const Vector& temp)
{
return (!(this->p == temp.p));
}
Vector Vector::operator-()
{
Vector opposite;
for (int i = 0; i < p.size(); i++)
{
opposite.p.push_back(p.at(i)*(-1.0));
}
return opposite;
}
Vector Vector::operator=(const double element)
{//把值改为3,长度不变
int _len = p.size();
p.clear();//容器重置
p.resize(_len, element);
return *this;
}
Vector Vector::operator+(const double element)
{
Vector dst;
for (int i = 0; i < p.size(); i++)
{
dst.p.push_back(p[i] + element);
}
return dst;
}
Vector Vector::operator-(const double element)
{
Vector dst;
for (vector<double>::iterator it = p.begin(); it < p.end(); ++it)
{
dst.p.push_back(*it - element);
}
return dst;
}
std::ostream& operator<<(std::ostream& os, const Vector& vector)
{
for (int i = 0; i < vector.p.size(); i++)
os << vector.p.at(i) << " ";
os << std::endl;
return os;
}
//把无效向量设置为0向量
Vector Vector::INVALID_VECTOR(0, 1.0);
int main(int argc, char *argv[])
{
// 通过传递元素素组初始化向量,最终将得到3个元素
double data1[] = {3.4, 4.4, 6.0};
Vector v(sizeof(data1) / sizeof(double), data1);
// 确保完备的初始化向量
assert(v.size() == sizeof(data1) / sizeof(double));
for (int idx = 0; idx < sizeof(data1) / sizeof(double); ++idx)
{
assert(v[idx] == data1[idx]);
}
// v的值应等于自身,且不会不等于自身
assert(v == v);
assert(!(v != v));
// v + v按元素分别求和的结果,相当于每个元素直接与2相乘
assert(v + v == v * 2);
// v - v按元素分别求和的结果,相当于v加上v的相反数
assert(v - v == v + (-v));
// v = 3的结果使向量的每个元素都变为3,因此等于直接初始化一个只有三个元素,且初始值为3的向量
assert((v = 3) == Vector(sizeof(data1) / sizeof(double), 3));
// v + 3的结果使向量的每个元素都加上3,因此等于直接初始化一个只有三个元素,且初始值为6的向量
// 而 v - 3则直接初始化一个只有三个元素,且初始值为0的向量
assert(v + 3 == Vector(sizeof(data1) / sizeof(double), 6));
assert(v - 3 == Vector(sizeof(data1) / sizeof(double), 0.0));
// 另行定义一个有十个元素,且每个元素值为5的向量
Vector v2(10, 5);
// 确保其正确初始化
assert(v2.size() == 10);
for (int idx = 0; idx < v2.size(); ++idx)
{
assert(v2[idx] == 5);
}
// 两个元素个数不相等的向量相加,其结果为【无效向量】
assert(v + v2 == Vector::INVALID_VECTOR);
return 0;
}
结果
- 实现了向量类的运算重载
- 代码没有输出,仅仅使用
assert()
函数验证功能的实现
总结
- 学到了vector容器的常见操作
- 友元法重载操作符<<
- 重载符号时,不带参数或者参数为
void