实验6 模板类、文件I/O和异常处理
1.实验任务4
Vector.hpp源代码:
点击查看代码
#pragma once
#include <iostream>
#include <stdexcept>
#include <algorithm> // for std::copy
template <typename T>
class Vector {
private:
T* data;
size_t size;
public:
// 构造函数
Vector(size_t n) : size(n), data(new T[n]) {}
// 初始化构造函数
Vector(size_t n, const T& value) : size(n), data(new T[n]) {
std::fill(data, data + n, value);
}
// 拷贝构造函数
Vector(const Vector& other) : size(other.size), data(new T[other.size]) {
std::copy(other.data, other.data + other.size, data);
}
// 析构函数
~Vector() {
delete[] data;
}
// 禁止拷贝赋值
Vector& operator=(const Vector&) = delete;
// 获取大小
size_t get_size() const {
return size;
}
// 通过索引访问元素
T& at(size_t index) {
if (index >= size) {
throw std::out_of_range("Index out of range");
}
return data[index];
}
// 通过索引访问元素(const 版本)
const T& at(size_t index) const {
if (index >= size) {
throw std::out_of_range("Index out of range");
}
return data[index];
}
// 重载 []
T& operator[](size_t index) {
return at(index);
}
// 重载 [](const 版本)
const T& operator[](size_t index) const {
return at(index);
}
};
// 友元函数,用于输出 Vector 中的数据
template <typename T>
void output(const Vector<T>& v) {
for (size_t i = 0; i < v.get_size(); ++i) {
std::cout << v[i] << " ";
}
std::cout << std::endl;
}
点击查看代码
#include <iostream>
#include "Vector.hpp"
void test1() {
using namespace std;
int n;
cout << "Enter n: ";
cin >> n;
Vector<double> x1(n);
for (auto i = 0; i < n; ++i)
x1.at(i) = i * 0.7;
cout << "x1: "; output(x1);
Vector<int> x2(n, 42);
const Vector<int> x3(x2);
cout << "x2: "; output(x2);
cout << "x3: "; output(x3);
x2.at(0) = 77;
x2.at(1) = 777;
cout << "x2: "; output(x2);
cout << "x3: "; output(x3);
}
void test2() {
using namespace std;
int n, index;
while (cout << "Enter n and index: ", cin >> n >> index) {
try {
Vector<int> v(n, n);
v.at(index) = -999;
cout << "v: "; output(v);
}
catch (const exception& e) {
cout << e.what() << endl;
}
}
}
int main() {
std::cout << "测试1: 模板类接口测试\n";
test1();
std::cout << "\n测试2: 模板类异常处理测试\n";
test2();
}
运行测试截图:
2.实验任务5
task5.cpp源码:
点击查看代码
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <fstream>
#include <algorithm>
using std::string;
using std::ostream;
using std::istream;
using std::setw;
using std::setprecision;
using std::setiosflags;
using std::ios_base;
class Contestant {
public:
Contestant() = default;
~Contestant() = default;
int get_num() const { return num; }
string get_major() const { return major; }
friend ostream& operator<<(ostream& out, const Contestant& c);
friend istream& operator>>(istream& in, Contestant& c);
private:
string no; // 学号
string name; // 姓名
string major; // 专业
int num; // 分数
};
// 友元函数实现
// 重载流插入运算符<<
ostream& operator<<(ostream& out, const Contestant& c) {
out << setiosflags(ios_base::left);
out << setw(10) << c.no
<< setw(10) << c.name
<< setw(10) << c.major
<< setw(5) << c.num;
return out;
}
// 重载流提取运算符>>
istream& operator>>(istream& in, Contestant& c) {
in >> c.no >> c.name >> c.major >> c.num;
return in;
}
bool compare(const Contestant& c1, const Contestant& c2) {
if (c1.get_major() > c2.get_major()) {
return false;
}
if (c1.get_major() == c2.get_major())
return c1.get_num() >c2.get_num();
return true;
}
void output(std::ostream& out, const std::vector<Contestant>& v) {
for (const auto& i : v)
out << i << std::endl;
}
void save(const std::string& filename, const std::vector<Contestant>& v) {
std::ofstream out(filename);
if (!out.is_open()) {
std::cout << "fail to open file to write\n";
return;
}
output(out, v);
out.close();
}
void load(const std::string& filename, std::vector<Contestant>& v) {
std::ifstream in(filename);
if (!in.is_open()) {
std::cout << "fail to open file to read\n";
return;
}
std::string title_line;
getline(in, title_line); // 跳过标题行
Contestant t;
while (in >> t)
v.push_back(t);
in.close();
}
void test() {
std::vector<Contestant> v;
load("data5.txt", v); // 从文件加载选手信息到对象v
std::sort(v.begin(), v.end(), compare);
output(std::cout, v); // 输出对象v中信息到屏幕
save("ans5.txt", v); // 把对象v中选手信息保存到文件
}
int main() {
test();
return 0;
}