实验二 类和对象_基础编程1
task1:
1 //t.h 2 #pragma once 3 #include<string> 4 class T { 5 public: 6 T(int x=0,int y=0); 7 T(const T &t); 8 T(T &&t); 9 ~T(); 10 void adjust(int ratio); 11 void display() const; 12 private: 13 int m1,m2; 14 public: 15 static int get_cnt(); 16 public: 17 static const std::string doc; 18 static const int max_cnt; 19 private: 20 static int cnt; 21 friend void func(); 22 }; 23 void func();
1 //t.cpp 2 #include"t.h" 3 #include<iostream> 4 #include<string> 5 using std::cout; 6 using std::endl; 7 using std::string; 8 const std::string T::doc{"a simple class sample"}; 9 const int T::max_cnt=999; 10 int T::cnt=0; 11 T::T(int x,int y):m1{x},m2{y}{ 12 ++cnt; 13 cout<<"T constructor called.\n"; 14 } 15 T::T(const T &t):m1{t.m1},m2{t.m2}{ 16 ++cnt; 17 cout<<"T copy constructor called.\n"; 18 } 19 T::T(T &&t):m1{t.m1},m2{t.m2}{ 20 ++cnt; 21 cout<<"T move constructor called.\n"; 22 } 23 T::~T() { 24 --cnt; 25 cout<<"T destructor called.\n"; 26 } 27 void T::adjust(int ratio){ 28 m1*=ratio; 29 m2*=ratio; 30 } 31 void T::display() const{ 32 cout<<"("<<m1<<","<<m2<<")"; 33 } 34 int T::get_cnt() { 35 return cnt; 36 } 37 void func(){ 38 T t5(42); 39 t5.m2=2049; 40 cout<<"t5=";t5.display() ;cout<<endl; 41 }
1 //task1.cpp 2 #include"t.h" 3 #include<iostream> 4 using std::cout; 5 using std::endl; 6 void test(); 7 int main(){ 8 test(); 9 cout<<"\nmain:\n"; 10 cout<<"T objects'current count:"<<T::get_cnt() <<endl; 11 } 12 void test(){ 13 cout<<"test class T\n"; 14 cout<<"T info:"<<T::doc<<endl; 15 cout<<"T objects'max count:"<<T::max_cnt<<endl; 16 cout<<"T objects'current count:"<<T::get_cnt() <<endl<<endl; 17 T t1; 18 cout<<"t1=";t1.display() ;cout<<endl; 19 T t2(3,4); 20 cout<<"t2=";t2.display();cout<<endl; 21 T t3(t2); 22 t3.adjust(2); 23 cout<<"t3=";t3.display() ;cout<<endl; 24 T t4(std::move(t2)); 25 cout<<"t3=";t4.display() ;cout<<endl; 26 cout<<"T objects'current count:'"<<T::get_cnt()<<endl; 27 func(); 28 }
截图:
问题1.1:
不可以删除;如果去掉的话,在整个函数中就不存在对func()函数的声明,只存在对友元函数func()函数进行声明,友元函数比不可逆;
问题1.2:
line9:默认构造函数,用于创建对象时进行初始化,初始化为默认值,一般情况下在无参数时进行调用。
line10:复制构造函数,在创建一个新对象时使用,通过复制已有数据进行初始化,当需要从现有对象创建新对象时,调用该函数。
line11:移动构造函数,将目前对象已有数据移动到一个新对象中,当前对象清空。
line12:析构函数:对对象在清除前进行清理,当该对象在该周期中完全结束工作调用该函数。
问题1.3:不能正确编译运行。
task2:
代码:
1 //Complex.h 2 #include<string> 3 #include<iostream> 4 class Complex{ 5 public: 6 static const std::string doc; 7 Complex(double r=0,double i=0); 8 Complex(const Complex &c); 9 const double get_real(); 10 const double get_imag(); 11 void add(const Complex &c); 12 friend Complex add(const Complex &c1,const Complex &c2); 13 friend bool is_equal(const Complex &c1,const Complex &c2); 14 friend bool is_not_equal(const Complex &c1,const Complex &c2); 15 friend double abs(const Complex &c); 16 friend void output(const Complex &c); 17 private: 18 double real; 19 double imag; 20 };
1 //Complex.cpp 2 #include<string> 3 #include<cmath> 4 using namespace std; 5 const string Complex::doc{"a simplified Complex class"}; 6 Complex::Complex(double r,double i):real{r},imag{i}{} 7 Complex::Complex(const Complex &c):real{c.real},imag{c.imag}{} 8 const double Complex::get_real(){ 9 return real; 10 } 11 const double Complex::get_imag(){ 12 return imag; 13 } 14 void Complex::add(const Complex &c) { 15 real += c.real; 16 imag += c.imag; 17 } 18 Complex add(const Complex &c1,const Complex &c2){ 19 return Complex(c1.real+c2.real,c1.imag+c2.imag); 20 } 21 bool is_equal(const Complex &c1,const Complex &c2){ 22 if(c1.real==c2.real&&c1.imag==c2.imag){ 23 return true; 24 } 25 } 26 bool is_not_equal(const Complex &c1,const Complex &c2){ 27 if(c1.real==c2.real&&c1.imag==c2.imag){ 28 return false; 29 } 30 } 31 double abs(const Complex &c){ 32 return sqrt(c.real*c.real+c.imag*c.imag); 33 } 34 void output(const Complex &c){ 35 if(c.imag>=0) 36 cout<<c.real<<"+"<<c.imag<<"i"<<endl; 37 else 38 cout<<c.real<<c.imag<<"i"<<endl; 39 }
1 //task2.cpp 2 #include "Complex.h" 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 using std::boolalpha; 8 9 void test() { 10 cout << "类成员测试: " << endl; 11 cout << Complex::doc << endl; 12 13 cout << endl; 14 15 cout << "Complex对象测试: " << endl; 16 Complex c1; 17 Complex c2(3, -4); 18 const Complex c3(3.5); 19 Complex c4(c3); 20 21 cout << "c1 = "; output(c1); cout << endl; 22 cout << "c2 = "; output(c2); cout << endl; 23 cout << "c3 = "; output(c3); cout << endl; 24 cout << "c4 = "; output(c4); cout << endl; 25 cout << "c4.real = " << c4.get_real() << ", c4.imag = " << c4.get_imag() << endl; 26 27 cout << endl; 28 29 cout << "复数运算测试: " << endl; 30 cout << "abs(c2) = " << abs(c2) << endl; 31 c1.add(c2); 32 cout << "c1 += c2, c1 = "; output(c1); cout << endl; 33 cout << boolalpha; 34 cout << "c1 == c2 : " << is_equal(c1, c2) << endl; 35 cout << "c1 != c3 : " << is_not_equal(c1, c3) << endl; 36 c4 = add(c2, c3); 37 cout << "c4 = c2 + c3, c4 = "; output(c4); cout << endl; 38 } 39 40 int main() { 41 test(); 42 }
截图:
task3:
代码:
1 #include<iostream> 2 #include<complex> 3 using std::cout; 4 using std::endl; 5 using std:: boolalpha; 6 using std::complex; 7 void test(){ 8 cout<<"标准库模板类complex测试:"<<endl; 9 complex<double>c1; 10 complex<double>c2(3,-4); 11 const complex<double>c3(3.5); 12 complex<double>c4(c3); 13 cout<<"c1="<<c1<<endl; 14 cout<<"c2="<<c2<<endl; 15 cout<<"c3="<<c3<<endl; 16 cout<<"c4="<<c4<<endl; 17 cout<<"c4.real="<<c4.real()<<", c4.imag="<<c1.imag()<<endl; 18 cout<<endl; 19 cout<<"复数运算测试:"<<endl; 20 cout<<"abs(c2)="<<abs(c2)<<endl; 21 c1+=c2; 22 cout<<"c1+=c2,c1="<<c1<<endl; 23 cout<<boolalpha; 24 cout<<"c1==c2:"<<(c1==c2)<<endl; 25 cout<<"c1!=c2:"<<(c1!=c2)<<endl; 26 c4=c2+c3; 27 cout<<"c4=c2+c3,c4="<<c4<<endl; 28 } 29 int main(){ 30 test(); 31 }
截图:
问题3.1:
使用的接口:
1:std::complex 2:c.real(),c.imag() 3:abs()
对比:可以通过调用real(),imag()直接访问复数的实部和虚部;
可以直接通过cout直接输出,不需要调用output函数进行输出。
task4:
代码:
1 #pragma once 2 #include<iostream> 3 #include<string> 4 using std::string; 5 class Fraction { 6 public: 7 Fraction(int up0 = 0, int down0 = 1); 8 Fraction(const Fraction& obj); 9 ~Fraction() {}; 10 int get_up () const; 11 int get_down () const; 12 Fraction negative(); 13 14 friend void output(Fraction f); 15 friend Fraction add(Fraction f1, Fraction f2); 16 friend Fraction sub(Fraction f1, Fraction f2); 17 friend Fraction mul(Fraction f1, Fraction f2); 18 friend Fraction div(Fraction f1, Fraction f2); 19 20 private: 21 int up, down; 22 23 public: 24 static const string doc; 25 }; 26 Fraction add(Fraction f1, Fraction f2); 27 Fraction sub(Fraction f1, Fraction f2); 28 Fraction mul(Fraction f1, Fraction f2); 29 Fraction div(Fraction f1, Fraction f2);
1 #include"Fraction.h" 2 #include<iostream> 3 #include<string> 4 #include<cmath> 5 using std::cout; 6 using std::endl; 7 using std::string; 8 const std::string Fraction ::doc{"Fraction类 v 0.01版。\n目前仅支持分数对象的构造、输出、加/减/乘/除运算.\n"}; 9 int gcd(int a, int b) {//求分子分母最大公因数 10 int t; 11 if (a == 0 || b == 0) 12 return 0; 13 while (b != 0) { 14 t = a % b; 15 a = b; 16 b = t; 17 } 18 return a; 19 } 20 int gcm(int a, int b) {//求分子分母最小公倍数 21 if (gcd(a, b) == 0) 22 return 0; 23 return a * b / gcd(a, b); 24 } 25 Fraction::Fraction(int up1 , int down1) :up{ up1}, down{ down1 } {}; 26 Fraction::Fraction(const Fraction& c) { 27 up = c.up; 28 down = c.down; 29 } 30 int Fraction::get_up ()const { return up; } 31 int Fraction::get_down ()const { return down; } 32 Fraction Fraction::negative() { 33 Fraction f; 34 if ( down > 0) { 35 f.up = -up; 36 f.down = down; 37 } 38 39 else if ( down < 0){ 40 f.up = up; 41 f.down = -down; 42 } 43 return f; 44 } 45 46 Fraction add(Fraction f1, Fraction f2) { 47 Fraction f; 48 int r= gcm(f1.down, f2.down); 49 f.up = f1.up * (r / f1.down) + f2.up * (r / f2.down); 50 f.down = r; 51 return f; 52 } 53 Fraction sub(Fraction f1, Fraction f2) { 54 Fraction f; 55 f.up = f1.up * f2.up; 56 f.down = f1.down * f2.down; 57 return f; 58 } 59 Fraction mul(Fraction f1, Fraction f2) { 60 Fraction f; 61 int r = gcm(f1.down, f2.down); 62 f.up = f1.up * (r / f1.down) - f2.up * (r / f2.down); 63 f.down = r; 64 return f; 65 } 66 Fraction div(Fraction f1, Fraction f2) { 67 int t; 68 Fraction f; 69 t = f2.up; 70 f2.up = f2.down; 71 f2.down = t; 72 f=sub(f1, f2); 73 return f; 74 } 75 void output(Fraction f) { 76 int r = abs(gcd(f.up, f.down)); 77 if (f.down == 0) 78 cout << "分母不能为0" << endl; 79 else if(f.up==0) 80 cout << f.up << endl; 81 else if (f.down > 0) 82 cout << f.up /r<< "/" << f.down/r << endl; 83 else if (f.down < 0) 84 cout << -(f.up/r) << "/" << -(f.down/r) << endl; 85 }
1 #include "Fraction.h" 2 #include <iostream> 3 4 using std::cout; 5 using std::endl; 6 7 8 void test1() { 9 cout << "Fraction类测试: " << endl; 10 cout << Fraction::doc << endl << endl; 11 12 Fraction f1(5); 13 Fraction f2(3, -4), f3(-18, 12); 14 Fraction f4(f3); 15 cout << "f1 = "; output(f1); cout << endl; 16 cout << "f2 = "; output(f2); cout << endl; 17 cout << "f3 = "; output(f3); cout << endl; 18 cout << "f4 = "; output(f4); cout << endl; 19 20 Fraction f5(f4.negative()); 21 cout << "f5 = "; output(f5); cout << endl; 22 cout << "f5.get_up() = " << f5.get_up() << ", f5.get_down() = " << f5.get_down() << endl; 23 24 cout << "f1 + f2 = "; output(add(f1, f2)); cout << endl; 25 cout << "f1 - f2 = "; output(sub(f1, f2)); cout << endl; 26 cout << "f1 * f2 = "; output(mul(f1, f2)); cout << endl; 27 cout << "f1 / f2 = "; output(div(f1, f2)); cout << endl; 28 cout << "f4 + f5 = "; output(add(f4, f5)); cout << endl; 29 } 30 31 void test2() { 32 Fraction f6(42, 55), f7(0, 3); 33 cout << "f6 = "; output(f6); cout << endl; 34 cout << "f7 = "; output(f7); cout << endl; 35 cout << "f6 / f7 = "; output(div(f6, f7)); cout << endl; 36 } 37 38 int main() { 39 cout << "测试1: Fraction类基础功能测试\n"; 40 test1(); 41 42 cout << "\n测试2: 分母为0测试: \n"; 43 test2(); 44 }
截图:
task5:
代码:
1 #pragma once 2 #include<string> 3 class SavingAccount{ 4 private: 5 int id; 6 double b; 7 double rate; 8 int ld; 9 double sum; 10 static double total; 11 void record(int date,double amount); 12 double accumulate(int date)const{ 13 return sum+b*(date-ld); 14 } 15 public: 16 SavingAccount(int date,int id,double rate); 17 int get_id() const {return id;} 18 double get_b() const{return b;} 19 double get_rate() const{return rate;} 20 static double get_total() { 21 return total; 22 } 23 void deposit(int date,double amount); 24 void withdraw(int date,double amount); 25 void settle(int date); 26 void show() const; 27 28 };
1 #include"account.h" 2 #include<cmath> 3 #include<iostream> 4 using namespace std; 5 double SavingAccount::total=0; 6 SavingAccount::SavingAccount(int date,int id,double rate) 7 :id(id),b(0),rate(rate),ld(date),sum(0){ 8 cout<<date<<"\t#"<<id<<" is created "<<endl; 9 } 10 void SavingAccount::record(int date,double amount){ 11 sum=accumulate(date); 12 ld=date; 13 amount=floor(amount*100+0.5)/100;//采用四舍五入的方法 14 b+=amount; 15 total+=amount; 16 cout<<date<<"\t#"<<id<<"\t"<<amount<<"\t"<<b<<endl; 17 } 18 void SavingAccount::deposit(int date,double amount){ 19 record(date,amount); 20 } 21 void SavingAccount::withdraw(int date,double amount){ 22 if(amount>get_b()) 23 cout<<"Error:not enough money"<<endl; 24 else 25 record(date,-amount); 26 } 27 void SavingAccount::settle(int date){ 28 double interest=accumulate(date)*rate/365; 29 if(interest!=0) 30 record(date,interest); 31 sum=0; 32 } 33 void SavingAccount::show() const{ 34 cout<<"#"<<id<<"\tBalance:"<<b; 35 }
1 #include"account.h" 2 #include<iostream> 3 using namespace std; 4 int main(){ 5 SavingAccount sa0(1,21325302,0.015); 6 SavingAccount sa1(1,58320212,0.015); 7 sa0.deposit(5,5000); 8 sa1.deposit(25,10000); 9 sa0.deposit(45,5500); 10 sa1.withdraw(60,4000); 11 sa0.settle(90); 12 sa1.settle(90); 13 sa0.show();cout<<endl; 14 sa1.show();cout<<endl; 15 cout<<"Total:"<<SavingAccount::get_total()<<endl; 16 return 0; 17 }
截图: