实验二
任务一:
T.h
1 #pragma once 2 #include <string> 3 // 类T: 声明 4 class T { 5 // 对象属性、方法 6 public: 7 T(int x = 0, int y = 0); // 普通构造函数 8 T(const T &t); // 复制构造函数 9 T(T &&t); 10 // 移动构造函数 11 ~T(); 12 // 析构函数 13 void adjust(int ratio); 14 void display() const; 15 private: 16 int m1, m2; 17 // 类属性、方法 18 public: 19 static int get_cnt(); 20 public: 21 static const std::string doc; 22 static const int max_cnt; 23 private: 24 static int cnt; 25 // 按系数成倍调整数据 26 // 以(m1, m2)形式显示T类对象信息 27 // 显示当前T类对象总数 28 // 类T的描述信息 29 // 类T对象上限 30 // 当前T类对象数目 31 // 类T友元函数声明 32 friend void func(); 33 }; 34 // 普通函数声明 35 void func();
T.cpp
1 #include "T.h" 2 #include <iostream> 3 #include <string> 4 // 类T实现 5 // static成员数据类外初始化 6 const std::string T::doc{"a simple class sample"}; 7 const int T::max_cnt = 999; 8 int T::cnt = 0; 9 // 类方法 10 int T::get_cnt() { 11 return cnt; 12 } 13 // 对象方法 14 T::T(int x, int y): m1{x}, m2{y} { 15 ++cnt; 16 std::cout << "T constructor called.\n"; 17 } 18 T::T(const T &t): m1{t.m1}, m2{t.m2} { 19 ++cnt; 20 std::cout << "T copy constructor called.\n"; 21 } 22 T::T(T &&t): m1{t.m1}, m2{t.m2} { 23 ++cnt; 24 std::cout << "T move constructor called.\n"; 25 } 26 T::~T() {--cnt; 27 std::cout << "T destructor called.\n"; 28 } 29 void T::adjust(int ratio) { 30 m1 *= ratio; 31 m2 *= ratio; 32 } 33 void T::display() const { 34 std::cout << "(" << m1 << ", " << m2 << ")" ; 35 } 36 // 普通函数实现 37 void func() { 38 T t5(42); 39 t5.m2 = 2049; 40 std::cout << "t5 = "; t5.display(); std::cout << '\n'; 41 }
task1.cpp
1 #include "T.h" 2 #include <iostream> 3 void test_T(); 4 int main() { 5 std::cout << "test Class T: \n"; 6 test_T(); 7 std::cout << "\ntest friend func: \n"; 8 func(); 9 } 10 void test_T() { 11 using std::cout; 12 using std::endl; 13 cout << "T info: " << T::doc << endl; 14 cout << "T objects'max count: " << T::max_cnt << endl; 15 cout << "T objects'current count: " << T::get_cnt() << endl << endl; 16 T t1; 17 cout << "t1 = "; t1.display(); cout << endl; 18 T t2(3, 4); 19 cout << "t2 = "; t2.display(); cout << endl; 20 T t3(t2); 21 t3.adjust(2); 22 cout << "t3 = "; t3.display(); cout << endl; 23 T t4(std::move(t2)); 24 cout << "t4 = "; t4.display(); cout << endl; 25 cout << "test: T objects'current count: " << T::get_cnt() << endl; 26 }

问题一:
不能友元声明只是声明此函数为友元,不声明函数本身

问题二:
T(int x = 0,int y = 0)初始化m1、m2,递增cnt;调用:T t1 ,T t2(3,4) ;
T(const T &t),复制已有的对象;调用:T t3(t2) ;
T(T &&t),复制已有对象,并将源对象设为安全状态;调用:T t4(std::move(t2));
~T(),清理资源,递减cnt;
问题三:
不能
移动后,产生了重定义,有歧义;
任务二:
complex.h
1 #pragma once 2 3 #include<string> 4 5 class Complex 6 { 7 public: 8 Complex(double real = 0,double imag = 0); 9 Complex(const Complex& c); 10 ~Complex(); 11 void add(const Complex& c); 12 static const std::string doc; 13 double get_real()const { 14 return real; 15 }; 16 double get_imag()const { 17 return imag; 18 }; 19 private: 20 double real, imag; 21 friend void output(const Complex& c); 22 friend double abs(const Complex& c); 23 friend Complex add(const Complex& c1, const Complex& c2); 24 friend bool is_equal(const Complex& c1, const Complex& c2); 25 friend bool is_not_equal(const Complex& c1, const Complex& c2); 26 }; 27 28 void output(const Complex& c); 29 double abs(const Complex& c); 30 Complex add(const Complex& c1, const Complex& c2); 31 bool is_equal(const Complex& c1, const Complex& c2); 32 bool is_not_equal(const Complex& c1, const Complex& c2);
complex.cpp
1 #include "Complex.h" 2 #include <iostream> 3 #include<string> 4 #include<math.h> 5 6 const std::string Complex::doc{ "a simplified complex calss" }; 7 8 9 10 Complex::Complex(double x, double y) : real{ x }, imag{ y } { 11 12 } 13 14 Complex::Complex(const Complex& c) :real{ c.real }, imag{c.imag} { 15 16 } 17 18 Complex::~Complex() { 19 20 } 21 22 void Complex::add(const Complex& c) { 23 real += c.real; 24 imag += c.imag; 25 } 26 27 void output(const Complex& c) { 28 if (c.imag >= 0) { 29 std::cout << c.real << " + " << c.imag << "i" << std::endl; 30 } 31 else { 32 std::cout << c.real << " - " << abs(c.imag) << "i" << std::endl; 33 } 34 } 35 36 double abs(const Complex& c) { 37 return sqrt(c.imag * c.imag + c.real * c.real); 38 } 39 40 Complex add(const Complex& c1, const Complex& c2) { 41 return Complex(c1.real + c2.real, c1.imag + c2.imag); 42 } 43 44 bool is_equal(const Complex& c1, const Complex& c2) { 45 if (c1.real == c2.real && c1.imag == c2.imag) { 46 return true; 47 } 48 else { 49 return false; 50 } 51 } 52 53 bool is_not_equal(const Complex& c1, const Complex& c2) { 54 if (c1.real == c2.real && c1.imag == c2.imag) { 55 return false; 56 } 57 else { 58 return true; 59 } 60 }
task2.cpp
1 #include"Complex.h" 2 #include <iostream> 3 #include <iomanip> 4 #include <complex> 5 void test_Complex(); 6 void test_std_complex(); 7 int main() { 8 std::cout << "*******测试1: 自定义类Complex*******\n"; 9 test_Complex(); 10 std::cout << "\n*******测试2: 标准库模板类complex*******\n"; 11 test_std_complex(); 12 } 13 void test_Complex() { 14 using std::cout; 15 using std::endl; 16 using std::boolalpha; 17 cout << "类成员测试: " << endl; 18 cout << Complex::doc << endl << endl; 19 cout << "Complex对象测试: " << endl; 20 Complex c1; 21 Complex c2(3, -4); 22 Complex c3(c2); 23 Complex c4 = c2; 24 const Complex c5(3.5); 25 cout << "c1 = "; output(c1); cout << endl; 26 cout << "c2 = "; output(c2); cout << endl; 27 cout << "c3 = "; output(c3); cout << endl; 28 cout << "c4 = "; output(c4); cout << endl; 29 cout << "c5.real = " << c5.get_real() 30 << ", c5.imag = " << c5.get_imag() << endl << endl; 31 cout << "复数运算测试: " << endl; 32 cout << "abs(c2) = " << abs(c2) << endl; 33 c1.add(c2); 34 cout << "c1 += c2, c1 = "; output(c1); cout << endl; 35 cout << boolalpha; 36 cout << "c1 == c2 : " << is_equal(c1, c2) << endl; 37 cout << "c1 != c2 : " << is_not_equal(c1, c2) << endl; 38 c4 = add(c2, c3); 39 cout << "c4 = c2 + c3, c4 = "; output(c4); cout << endl; 40 } 41 void test_std_complex() { 42 using std::cout; 43 using std::endl; 44 using std::boolalpha; 45 cout << "std::complex<double>对象测试: " << endl; 46 std::complex<double> c1; 47 std::complex<double> c2(3, -4); 48 std::complex<double> c3(c2); 49 std::complex<double> c4 = c2; 50 const std::complex<double> c5(3.5); 51 cout << "c1 = " << c1 << endl; 52 cout << "c2 = " << c2 << endl; 53 cout << "c3 = " << c3 << endl; 54 cout << "c4 = " << c4 << endl; 55 cout << "c5.real = " << c5.real() 56 << ", c5.imag = " << c5.imag() << endl << endl; 57 cout << "复数运算测试: " << endl; 58 cout << "abs(c2) = " << abs(c2) << endl; 59 c1 += c2; 60 cout << "c1 += c2, c1 = " << c1 << endl; 61 cout << boolalpha; 62 cout << "c1 == c2 : " << (c1 == c2) << endl; 63 cout << "c1 != c2 : " << (c1 != c2) << endl; 64 c4 = c2 + c3; 65 cout << "c4 = c2 + c3, c4 = " << c4 << endl; 66 }

问题一:标准模板库更整洁,有
问题二:1、需要,需要real,image去进行运算
2、否,abs是独立的,通过接口访问数据
3、必须使用隐私数据且不是成员函数时
问题三:需将拷贝构造函数声明为explicit
任务三:
PlayerControl.h
1 #pragma once 2 #pragma once 3 #include <string> 4 enum class ControlType { Play, Pause, Next, Prev, Stop, Unknown }; 5 class PlayerControl { 6 public: 7 PlayerControl(); 8 static int get_cnt(); 9 ControlType parse(const std::string& control_str); // 实现std::string --> ControlType转换 10 void execute(ControlType cmd) const; // 执行控制操作(以打印输出模拟) 11 private: 12 static int total_cnt; 13 };
PlayerControl.cpp
1 #include "PlayerControl.h" 2 #include <iostream> 3 #include <algorithm> 4 int PlayerControl::total_cnt = 0; 5 PlayerControl::PlayerControl() {} 6 // 待补足 7 8 9 10 // 4. 每次成功调用parse时递增total_cnt 11 ControlType PlayerControl::parse(const std::string& control_str) { 12 std::string s1; 13 for (auto c : control_str){ 14 s1 += tolower(c); 15 } 16 if (s1 == "play") { 17 total_cnt++; 18 return ControlType::Play; 19 } 20 if (s1 == "pause") { 21 total_cnt++; 22 return ControlType::Pause; 23 } 24 if (s1 == "next") { 25 total_cnt++; 26 return ControlType::Next; 27 } 28 if (s1 == "prev") { 29 total_cnt++; 30 return ControlType::Prev; 31 } 32 if (s1 == "stop") { 33 total_cnt++; 34 return ControlType::Stop; 35 } 36 return ControlType::Unknown; 37 } 38 void PlayerControl::execute(ControlType cmd) const { 39 switch (cmd) { 40 case ControlType::Play: std::cout << "[play] Playing music...\n"; break; 41 case ControlType::Pause: std::cout << "[Pause] Music paused\n"; break; 42 case ControlType::Next: std::cout << "[Next] Skipping to next track\n"; break; 43 case ControlType::Prev: std::cout << "[Prev] Back to previous track\n"; break; 44 case ControlType::Stop: std::cout << "[Stop] Music stopped\n"; break; 45 default: std::cout << "[Error] unknown control\n"; break; 46 } 47 } 48 int PlayerControl::get_cnt() { 49 return total_cnt; 50 }
task3.cpp
1 #include "PlayerControl.h" 2 #include <iostream> 3 void test() { 4 PlayerControl controller; 5 std::string control_str; 6 std::cout << "Enter Control: (play/pause/next/prev/stop/quit):\n"; 7 while (std::cin >> control_str) { 8 if (control_str == "quit") 9 break; 10 11 ControlType cmd = controller.parse(control_str); 12 controller.execute(cmd); 13 std::cout << "Current Player control: " << PlayerControl::get_cnt() << "\n\n"; 14 } 15 } 16 int main() { 17 test(); 18 }

任务四:
Fraction.h
1 #pragma once 2 #include<iostream> 3 4 5 class Fraction 6 { 7 public: 8 static const std::string doc; 9 Fraction(int up = 0, int down = 1); 10 Fraction(const Fraction& f); 11 ~Fraction(); 12 int get_up()const { return up; }; 13 int get_down()const { return down; }; 14 Fraction negative(); 15 16 private: 17 int up, down; 18 19 }; 20 21 Fraction add(const Fraction& f1, const Fraction& f2); 22 Fraction sub(const Fraction& f1, const Fraction& f2); 23 Fraction mul(const Fraction& f1, const Fraction& f2); 24 Fraction div(const Fraction& f1, const Fraction& f2); 25 void output(const Fraction f);
Fraction.cpp
1 #include"Fraction.h" 2 #include<iostream> 3 #include<math.h> 4 5 const std::string Fraction::doc{ "Fraction类 v 0.01版. \n目前仅支持分数对象的构造、输出、加 / 减 / 乘 / 除运算\n" }; 6 7 Fraction::Fraction(int x, int y) :up{ x }, down{ y } { 8 if (y == 0) { 9 std::cout << "[Error]分母不应为0" << std::endl; 10 } 11 int i = 1; 12 int a = 1; 13 while (i <= abs(up) && i <= abs(down)) { 14 if (up % i == 0 && down % i == 0) { 15 a = i; 16 } 17 i++; 18 } 19 up /= a; 20 down /= a; 21 if (up < 0 && down < 0) { 22 up = abs(up); 23 down = abs(down); 24 } 25 if (up > 0 && down < 0) { 26 up = -up; 27 down = -down; 28 } 29 }; 30 31 Fraction::Fraction(const Fraction& f) :up{ f.up }, down{ f.down } {}; 32 33 Fraction::~Fraction() {}; 34 35 Fraction Fraction::negative() { 36 Fraction f1(-up,down); 37 return f1; 38 } 39 40 Fraction add(const Fraction& f1, const Fraction& f2) { 41 const int down = f1.get_down() * f2.get_down(); 42 const int up = f1.get_up() * f2.get_down() + f2.get_up() * f1.get_down(); 43 Fraction f(up, down); 44 return f; 45 } 46 Fraction sub(const Fraction& f1, const Fraction& f2) { 47 const int down = f1.get_down() * f2.get_down(); 48 const int up = f1.get_up() * f2.get_down() - f2.get_up() * f1.get_down(); 49 Fraction f(up, down); 50 return f; 51 } 52 Fraction mul(const Fraction& f1, const Fraction& f2) { 53 const int down = f1.get_down() * f2.get_down(); 54 const int up = f1.get_up() * f2.get_up(); 55 Fraction f(up, down); 56 return f; 57 58 } 59 Fraction div(const Fraction& f1, const Fraction& f2) { 60 const int down = f1.get_down() * f2.get_up(); 61 const int up = f1.get_up() * f2.get_down(); 62 Fraction f(up, down); 63 return f; 64 } 65 void output(const Fraction f){ 66 67 switch (f.get_down()) { 68 case 0 : 69 break; 70 71 case 1 : 72 std::cout << f.get_up() << std::endl; 73 break; 74 default: 75 if (f.get_up() == 0) { 76 std::cout << "0" << std::endl; 77 } 78 else { 79 std::cout << f.get_up() << "/" << f.get_down() << std::endl; 80 } 81 } 82 }
task4.cpp
1 #include "Fraction.h" 2 #include <iostream> 3 void test1(); 4 void test2(); 5 int main() { 6 std::cout << "测试1: Fraction类基础功能测试\n"; 7 test1(); 8 std::cout << "\n测试2: 分母为0测试: \n"; 9 test2(); 10 } 11 void test1() { 12 using std::cout; 13 using std::endl; 14 cout << "Fraction类测试: " << endl; 15 cout << Fraction::doc << endl << endl; 16 Fraction f1(5); 17 Fraction f2(3, -4), f3(-18, 12); 18 Fraction f4(f3); 19 cout << "f1 = "; output(f1); cout << endl; 20 cout << "f2 = "; output(f2); cout << endl; 21 cout << "f3 = "; output(f3); cout << endl; 22 cout << "f4 = "; output(f4); cout << endl; 23 24 const Fraction f5(f4.negative()); 25 cout << "f5 = "; output(f5); cout << endl; 26 cout << "f5.get_up() = " << f5.get_up() 27 << ", f5.get_down() = " << f5.get_down() << endl; 28 cout << "f1 + f2 = "; output(add(f1, f2)); cout << endl; 29 cout << "f1 - f2 = "; output(sub(f1, f2)); cout << endl; 30 cout << "f1 * f2 = "; output(mul(f1, f2)); cout << endl; 31 cout << "f1 / f2 = "; output(div(f1, f2)); cout << endl; 32 cout << "f4 + f5 = "; output(add(f4, f5)); cout << endl; 33 } 34 void test2() { 35 using std::cout; 36 using std::endl; 37 Fraction f6(42, 55), f7(0, 3); 38 cout << "f6 = "; output(f6); cout << endl; 39 cout << "f7 = "; output(f7); cout << endl; 40 cout << "f6 / f7 = "; output(div(f6, f7)); cout << endl; 41 }

问题:命名空间+自由函数
友元方案虽可以直接访问,但会导致封装密封性被破坏且难维护;

浙公网安备 33010602011771号