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

问题1:YES
问题2:普通构造函数功能:对类对象进行初始化 调用时机:定义一个类对象的时候
复制构造函数功能:用一个已经定义了的类对象去初始化另一个类对象 调用时机:用类对象初始化新的类对象
移动构造函数功能:将一个初始化过的对象转移给另一个对象 调用时机:用右值初始化新的对象
析构函数功能:释放对象占有的资源 调用时机:该对象生命周期结束的时候
问题3:可以正常运行
tsak2:
1 #pragma once 2 3 #include<string> 4 5 class complex{ 6 public: 7 static const std::string doc; 8 9 private: 10 double real; 11 double imag; 12 13 public: 14 complex(double x=0.0,double y=0.0); 15 complex(const complex&c); 16 17 double get_real()const; 18 double get_imag()const; 19 void add(const complex& c); 20 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(complex x,complex y); 25 friend bool is_not_equal(complex a,complex b); 26 };
1 #include"complex.h" 2 #include<iostream> 3 #include<string> 4 #include<cmath> 5 6 const std::string complex::doc{"a simplified complex class"}; 7 8 complex::complex(double x,double y):real{x},imag{y}{}; 9 complex::complex(const complex&c):real{c.real},imag{c.imag}{}; 10 11 double complex::get_real()const{ 12 return real; 13 } 14 double complex::get_imag()const{ 15 return imag; 16 } 17 void complex::add(const complex& c){ 18 real+=c.real; 19 imag+=c.imag; 20 } 21 22 void output(const complex& c){ 23 if(c.imag>=0) 24 std::cout<<c.real<<"+"<<c.imag<<"i"; 25 else 26 std::cout<<c.real<<c.imag<<"i"; 27 } 28 double abs(const complex& c){ 29 return std::sqrt(c.real*c.real+c.imag*c.imag); 30 } 31 complex add(const complex& c1,const complex& c2){ 32 return complex(c1.real+c2.real,c1.imag+c2.imag); 33 } 34 bool is_equal(complex c1,complex c2){ 35 if((c1.real==c2.real)&&(c1.imag==c2.imag)) 36 return true; 37 else 38 return false; 39 } 40 bool is_not_equal(complex c1,complex c2){ 41 if((c1.real==c2.real)&&(c1.imag==c2.imag)) 42 return false; 43 else 44 return true; 45 }
1 #include"complex.h" 2 #include <iostream> 3 #include <iomanip> 4 #include <complex> 5 6 void test_complex(); 7 void test_std_complex(); 8 9 10 int main() { 11 std::cout << "*******测试1: 自定义类Complex*******\n"; 12 test_complex(); 13 14 std::cout << "\n*******测试2: 标准库模板类complex*******\n"; 15 test_std_complex(); 16 } 17 18 void test_complex() { 19 using std::cout; 20 using std::endl; 21 using std::boolalpha; 22 23 24 cout << "类成员测试: " << endl; 25 cout << complex::doc << endl << endl; 26 27 28 cout << "Complex对象测试: " << endl; 29 complex c1; 30 complex c2(3, -4); 31 complex c3(c2); 32 complex c4 = c2; 33 const complex c5(3.5); 34 35 cout << "c1 = "; output(c1); cout << endl; 36 cout << "c2 = "; output(c2); cout << endl; 37 cout << "c3 = "; output(c3); cout << endl; 38 cout << "c4 = "; output(c4); cout << endl; 39 cout << "c5.real = " << c5.get_real() 40 << ", c5.imag = " << c5.get_imag() << endl << endl; 41 42 cout << "复数运算测试: " << endl; 43 cout << "abs(c2) = " << abs(c2) << endl; 44 c1.add(c2); 45 cout << "c1 += c2, c1 = "; output(c1); cout << endl; 46 cout << boolalpha; 47 cout << "c1 == c2 : " << is_equal(c1, c2) << endl; 48 cout << "c1 != c2 : " << is_not_equal(c1, c2) << endl; 49 c4 = add(c2, c3); 50 cout << "c4 = c2 + c3, c4 = "; output(c4); cout << endl; 51 } 52 53 54 void test_std_complex() { 55 using std::cout; 56 using std::endl; 57 using std::boolalpha; 58 59 cout << "std::complex<double>对象测试: " << endl; 60 std::complex<double> c1; 61 std::complex<double> c2(3, -4); 62 std::complex<double> c3(c2); 63 std::complex<double> c4 = c2; 64 const std::complex<double> c5(3.5); 65 66 67 cout << "c1 = " << c1 << endl; 68 cout << "c2 = " << c2 << endl; 69 cout << "c3 = " << c3 << endl; 70 cout << "c4 = " << c4 << endl; 71 72 73 cout << "c5.real = " << c5.real() 74 << ", c5.imag = " << c5.imag() << endl << endl; 75 76 77 cout << "复数运算测试: " << endl; 78 cout << "abs(c2) = " << abs(c2) << endl; 79 c1 += c2; 80 cout << "c1 += c2, c1 = " << c1 << endl; 81 cout << boolalpha; 82 cout << "c1 == c2 : " << (c1 == c2)<< endl; 83 cout << "c1 != c2 : " << (c1 != c2) << endl; 84 c4 = c2 + c3; 85 cout << "c4 = c2 + c3, c4 = " << c4 << endl; 86 }


问题1:标准库模板类的形式更简洁。 有关联 例如add(c1+c2)从运算的层面来说就是计算c1+c2
问题2-1:可以不访问,因为提供了共有的get_real()和get_imag()函数,可以由此获得数据
问题2-2:没有
问题2-3:必须要访问私有数据并且没有公有函数接口可以获得数据的时候
问题3:显式声明构造函数
task3:
1 #pragma once 2 #include <string> 3 4 enum class ControlType {Play, Pause, Next, Prev, Stop, Unknown}; 5 6 class playercontrol { 7 public: 8 playercontrol(); 9 10 ControlType parse(const std::string& control_str); // 实现std::string -->ControlType转换 11 12 void execute(ControlType cmd) const; // 执行控制操作(以打印输出模拟) 13 14 static int get_cnt(); 15 16 private: 17 static int total_cnt; 18 };
1 #include "playercontrol.h" 2 #include <iostream> 3 #include <algorithm> 4 #include<string> 5 #include<cctype> 6 7 int playercontrol::total_cnt = 0; 8 playercontrol::playercontrol() {} 9 10 ControlType playercontrol::parse(const std::string& control_str) { 11 total_cnt+=1; 12 int len=control_str.length(); 13 std::string control_strtemp; 14 control_strtemp=std::toupper(control_str[0]); 15 for(int i=1;i<len;++i) 16 control_strtemp+=std::tolower(control_str[i]); 17 18 if(control_strtemp=="Play") 19 return ControlType::Play; 20 else if(control_strtemp=="Pause") 21 return ControlType::Pause; 22 else if(control_strtemp=="Next") 23 return ControlType::Next; 24 else if(control_strtemp=="Prev") 25 return ControlType::Prev; 26 else if(control_strtemp=="Stop") 27 return ControlType::Stop; 28 else 29 return ControlType::Unknown; 30 31 } 32 void playercontrol::execute(ControlType cmd) const { 33 switch (cmd) { 34 case ControlType::Play: std::cout << "[play] Playing music...\n"; break; 35 case ControlType::Pause: std::cout << "[Pause] Music paused\n"; break; 36 case ControlType::Next: std::cout << "[Next] Skipping to next track\n"; break; 37 case ControlType::Prev: std::cout << "[Prev] Back to previous track\n"; break; 38 case ControlType::Stop: std::cout << "[Stop] Music stopped\n"; break; 39 default: std::cout << "[Error] unknown control\n"; break; 40 } 41 } 42 43 int playercontrol::get_cnt() { 44 return total_cnt; 45 }
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 8 while(std::cin >> control_str) { 9 if(control_str == "quit") 10 break; 11 12 ControlType cmd = controller.parse(control_str); 13 controller.execute(cmd); 14 std::cout << "Current Player control: " << playercontrol::get_cnt() << "\n\n"; 15 } 16 } 17 18 int main() { 19 test(); 20 }

task4:
1 #pragma once 2 3 #include<string> 4 5 class Fraction{ 6 public: 7 static const std::string doc; 8 9 private: 10 int up; 11 int down; 12 13 public: 14 Fraction(); 15 Fraction(int x,int y=1); 16 Fraction(const Fraction& f); 17 18 int get_up(); 19 int get_down(); 20 Fraction negative(); 21 int gcd();//求分母和分子的最大公约数 22 int judge();//判断分数的正负 23 24 25 friend void output(Fraction f); 26 friend Fraction add(Fraction f1,Fraction f2); 27 friend Fraction sub(Fraction f1,Fraction f2); 28 friend Fraction mul(Fraction f1,Fraction f2); 29 friend Fraction div(Fraction f1,Fraction f2); 30 31 };
1 #include"Fraction.h" 2 #include<iostream> 3 #include<algorithm> 4 5 const std::string Fraction::doc{"Fraction类v0。01版\n目前仅支持分数对象的构造、输出、加/减/乘/除运算"}; 6 7 Fraction::Fraction(){} 8 Fraction::Fraction(int x,int y):up{x},down{y}{} 9 Fraction::Fraction(const Fraction& f):up{f.up},down{f.down}{} 10 11 //求分母和分子的最大公约数 12 int Fraction::gcd(){ 13 int temp; 14 int a=std::abs(up); 15 int b=std::abs(down); 16 while(b!=0){ 17 temp=b; 18 b=a%b; 19 a=temp; 20 } 21 return a; 22 } 23 24 //判断分数正负 25 int Fraction::judge(){ 26 if(up*down>0) 27 return 1; 28 else if(up*down<0) 29 return -1; 30 else 31 return 0; 32 } 33 34 //返回分子 35 int Fraction::get_up(){ 36 return up; 37 } 38 39 //返回分母 40 int Fraction::get_down(){ 41 return down; 42 } 43 44 //求负 45 Fraction Fraction::negative(){ 46 if(judge()>0&&gcd()!=1){ 47 up/=gcd(); 48 down/=gcd(); 49 } 50 else if(judge()<0&&gcd()!=1){ 51 up/=gcd(); 52 down/=gcd(); 53 } 54 if(judge()==1) 55 return Fraction(std::abs(up)*(-1),std::abs(down)); 56 else if(judge()==-1) 57 return Fraction(std::abs(up),std::abs(down)); 58 else 59 return Fraction(0); 60 } 61 62 63 //输出分数 64 void output(Fraction f){ 65 if(f.judge()>0&&f.gcd()!=1){ 66 f.up/=f.gcd(); 67 f.down/=f.gcd(); 68 } 69 else if(f.judge()<0&&f.gcd()!=1){ 70 f.up/=f.gcd(); 71 f.down/=f.gcd(); 72 } 73 74 if(f.judge()==1){ 75 if(f.down==1) 76 std::cout<<std::abs(f.up)<<std::endl; 77 else 78 std::cout<<std::abs(f.up)<<"/"<<std::abs(f.down)<<std::endl; 79 } 80 else if(f.judge()==-1){ 81 if(f.down==1) 82 std::cout<<"-"<<std::abs(f.down)<<std::endl; 83 else 84 std::cout<<"-"<<std::abs(f.up)<<"/"<<std::abs(f.down)<<std::endl; 85 } 86 else if(f.judge()==0&&f.down!=0){ 87 std::cout<<"0"<<std::endl; 88 } 89 else 90 std::cout<<"分母不能为0"; 91 } 92 93 //加法 94 Fraction add(Fraction f1,Fraction f2){ 95 Fraction t; 96 int a=std::abs(f1.up); 97 int b=std::abs(f1.down); 98 int c=std::abs(f2.up); 99 int d=std::abs(f2.down); 100 101 if(f1.judge()==0&&f2.judge()==0) 102 return Fraction(0); 103 else if(f1.judge()==0) 104 return f2; 105 else if(f2.judge()==0) 106 return f1; 107 108 t.down=b*d; 109 if(f1.judge()==1&&f2.judge()==1){ 110 t.up=a*d+b*c; 111 if(t.gcd()!=1){ 112 t.up/=t.gcd(); 113 t.down/=t.gcd(); 114 } 115 return t; 116 } 117 else if(f1.judge()==1&&f2.judge()==-1){ 118 t.up=a*d-b*c; 119 if(t.gcd()!=1){ 120 t.up/=t.gcd(); 121 t.down/=t.gcd(); 122 } 123 if(t.judge()>0) 124 return t; 125 else if(t.judge()<0) 126 return Fraction(std::abs(t.up)*(-1),std::abs(t.down)); 127 else 128 return Fraction(0); 129 } 130 else if(f1.judge()==-1&&f2.judge()==1){ 131 t.up=c*b-a*d; 132 if(t.gcd()!=1){ 133 t.up/=t.gcd(); 134 t.down/=t.gcd(); 135 } 136 if(t.judge()>0) 137 return t; 138 else if(t.judge()<0) 139 return Fraction(std::abs(t.up)*(-1),std::abs(t.down)); 140 else 141 return Fraction(0); 142 } 143 else{ 144 t.up=(a*d+b*c)*(-1); 145 if(t.gcd()!=1){ 146 t.up/=t.gcd(); 147 t.down/=t.gcd(); 148 } 149 return Fraction(std::abs(t.up)*(-1),std::abs(t.down)); 150 } 151 152 } 153 154 //减法 155 Fraction sub(Fraction f1,Fraction f2){ 156 Fraction t; 157 if(f1.judge()==0&&f2.judge()==0) 158 return Fraction(0); 159 else if(f1.judge()==0) 160 return f2.negative(); 161 else if(f2.judge()==0) 162 return f1; 163 164 t=f2.negative(); 165 return add(f1,t); 166 } 167 168 //乘法 169 Fraction mul(Fraction f1,Fraction f2){ 170 Fraction t; 171 if(f1.judge()==0||f2.judge()==0) 172 return Fraction(0); 173 174 t.down=std::abs(f1.down)*std::abs(f2.down); 175 t.up=std::abs(f1.up)*std::abs(f2.up); 176 if(t.gcd()!=1){ 177 t.up/=t.gcd(); 178 t.down/=t.gcd(); 179 } 180 if(f1.judge()*f2.judge()>0) 181 return t; 182 else 183 return Fraction(t.up*(-1),t.down); 184 } 185 186 //除法 187 Fraction div(Fraction f1,Fraction f2){ 188 Fraction t; 189 if(f2.judge()==0) 190 return Fraction(0,0); 191 192 if(f1.judge()==0) 193 return Fraction(0); 194 195 t.down=std::abs(f1.down)*std::abs(f2.up); 196 t.up=std::abs(f1.up)*std::abs(f2.down); 197 if(t.gcd()!=1){ 198 t.up/=t.gcd(); 199 t.down/=t.gcd(); 200 } 201 if(f1.judge()*f2.judge()>0) 202 return t; 203 else 204 return Fraction(t.up*(-1),t.down); 205 }
1 #include"Fraction.h" 2 #include <iostream> 3 4 void test1(); 5 void test2(); 6 7 int main() { 8 std::cout << "测试1: Fraction类基础功能测试\n"; 9 test1(); 10 11 std::cout << "\n测试2: 分母为0测试: \n"; 12 test2(); 13 } 14 15 void test1() { 16 using std::cout; 17 using std::endl; 18 19 cout << "Fraction类测试: " << endl; 20 cout << Fraction::doc << endl << endl; 21 22 Fraction f1(5); 23 Fraction f2(3, -4), f3(-18, 12); 24 Fraction f4(f3); 25 cout << "f1 = "; output(f1); cout << endl; 26 cout << "f2 = "; output(f2); cout << endl; 27 cout << "f3 = "; output(f3); cout << endl; 28 cout << "f4 = "; output(f4); cout << endl; 29 30 31 Fraction f5(f4.negative()); 32 cout << "f5 = "; output(f5); cout << endl; 33 cout << "f5.get_up() = " << f5.get_up() 34 << ", f5.get_down() = " << f5.get_down() << endl; 35 36 37 cout << "f1 + f2 = "; output(add(f1, f2)); cout << endl; 38 cout << "f1 - f2 = "; output(sub(f1, f2)); cout << endl; 39 cout << "f1 * f2 = "; output(mul(f1, f2)); cout << endl; 40 cout << "f1 / f2 = "; output(div(f1, f2)); cout << endl; 41 cout << "f4 + f5 = "; output(add(f4, f5)); cout << endl; 42 } 43 44 45 void test2() { 46 using std::cout; 47 using std::endl; 48 49 Fraction f6(42, 55), f7(0, 3); 50 51 cout << "f6 = "; output(f6); cout << endl; 52 cout << "f7 = "; output(f7); cout << endl; 53 cout << "f6 / f7 = "; output(div(f6, f7)); cout << endl; 54 }


问题:我选择的是友元 友元可以直接访问类的私有成员 但是这个分数计算需要改变得到的分数的分子和分母的值,对于安全性有一定的影响

浙公网安备 33010602011771号