实验2 类和对象_基础编程1

实验任务1

代码

t.h

 1 #pragma once
 2 #include <string>
 3 
 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 
11     void adjust(int ratio);      
12     void display() const;           
13 
14 private:
15     int m1, m2;
16 
17 public:
18     static int get_cnt();          
19 
20 public:
21     static const std::string doc;       
22     static const int max_cnt;          
23 
24 private:
25     static int cnt;         
26 
27     friend void func();
28 };
29 
30 void func();

t.cpp

 1 #include "t.h"
 2 #include <iostream>
 3 #include <string>
 4 
 5 using std::cout;
 6 using std::endl;
 7 using std::string;
 8 
 9 const std::string T::doc{"a simple class sample"};
10 const int T::max_cnt = 999;
11 int T::cnt = 0;
12 
13 
14 T::T(int x, int y): m1{x}, m2{y} { 
15     ++cnt; 
16     cout << "T constructor called.\n";
17 } 
18 
19 T::T(const T &t): m1{t.m1}, m2{t.m2} {
20     ++cnt;
21     cout << "T copy constructor called.\n";
22 }
23 
24 T::T(T &&t): m1{t.m1}, m2{t.m2} {
25     ++cnt;
26     cout << "T move constructor called.\n";
27 }    
28 
29 T::~T() {
30     --cnt;
31     cout << "T destructor called.\n";
32 }           
33 
34 void T::adjust(int ratio) {
35     m1 *= ratio;
36     m2 *= ratio;
37 }    
38 
39 void T::display() const {
40     cout << "(" << m1 << ", " << m2 << ")" ;
41 }     
42 
43 int T::get_cnt() {
44    return cnt;
45 }
46 
47 void func() {
48     T t5(42);
49     t5.m2 = 2049;
50     cout << "t5 = "; t5.display(); cout << endl;
51 }

task1.cpp

 1 #include "t.h"
 2 #include <iostream>
 3 
 4 using std::cout;
 5 using std::endl;
 6 
 7 void test();
 8 
 9 int main() {
10     test();
11     cout << "\nmain: \n";
12     cout << "T objects'current count: " << T::get_cnt() << endl;
13 }
14 
15 void test() {
16     cout << "test class T: \n";
17     cout << "T info: " << T::doc << endl;
18     cout << "T objects'max count: " << T::max_cnt << endl;
19     cout << "T objects'current count: " << T::get_cnt() << endl << endl;
20 
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 << "t3 = "; t4.display(); cout << endl;
34 
35     cout << "T objects'current count: " << T::get_cnt() << endl;
36 
37     func();
38 }

编译截图

 问题1

不能。在 t.h 中,第 36 行(friend void func();)声明 func 为类 T 的友元函数。如果我们去掉这行友元声明,那么在 func 函数中访问 T 的私有成员(例如 t5.m2 = 2049;)会导致编译错误,因为没有友元声明 func 就不能访问 T 的私有数据。

问题2

普通构造函数 T(int x = 0, int y = 0);
功能:允许用户通过传递两个整数参数来初始化对象的 m1 和 m2 属性,如果未传入参数,则默认为 0。
调用时机:当创建新对象并用参数(或默认值)初始化时调用。

复制构造函数 T(const T &t);
功能:允许通过拷贝已有对象来创建新对象,将传入对象 t 的成员数据 m1 和 m2 复制到新对象。
调用时机:当用已有对象初始化新对象(例如 T t3(t2);)或以传值方式将对象传递给函数时调用。

移动构造函数 T(T &&t);
功能:通过移动而非复制的方式初始化新对象,这个构造函数将传入对象 t 的资源转移到新对象中。
调用时机:当用临时对象或右值(如 std::move 后的对象)初始化新对象时调用。

析构函数 ~T();
功能:用于清理和释放资源,并减少 cnt 计数。
调用时机:当对象生命周期结束、即将被销毁时自动调用。

问题3

在 t.cpp 中的第 13-15 行静态成员的初始化代码是 const std::string T::doc{"a simple class sample"};,const int T::max_cnt = 999; 和 int T::cnt = 0;。这部分代码初始化了静态常量和计数器,放置在类外部初始化符合 C++ 静态数据成员的初始化规则。

如果将它们移动到 t.h 中,则会导致链接错误,因为对于静态成员,通常需要在类外单独定义。

实验任务2

代码

  1 #ifndef COMPLEX_H  
  2 
  3 #define COMPLEX_H  
  4 
  5 
  6 
  7 #include <iostream>  
  8 
  9 #include <cmath>  
 10 
 11 #include <string>  
 12 
 13 
 14 
 15 class Complex {  
 16 
 17 public:  
 18 
 19     static const std::string doc;   
 20 
 21 
 22 
 23 private:  
 24 
 25     double real; 
 26 
 27     double imag;  
 28 
 29 
 30 
 31 public:  
 32 
 33      
 34 
 35     Complex();  
 36 
 37     Complex(double r);  
 38 
 39     Complex(double r, double i); 
 40 
 41     Complex(const Complex &c);  
 42 
 43 
 44 
 45    
 46 
 47     double get_real() const;  
 48 
 49     double get_imag() const;  
 50 
 51     Complex add(const Complex &c) const;  
 52 
 53     bool is_equal(const Complex &c) const;  
 54 
 55     bool is_not_equal(const Complex &c) const;  
 56 
 57     void output() const;  
 58 
 59     double abs() const;  
 60 
 61 };  
 62 
 63 
 64 
 65 #endif 
 66 
 67 
 68 
 69 #include "Complex.h"  
 70 
 71 const std::string Complex::doc = "a simplified complex class";    
 72 
 73 Complex::Complex() : real(0), imag(0) {}   
 74 
 75 Complex::Complex(double r) : real(r), imag(0) {}  
 76 
 77 Complex::Complex(double r, double i) : real(r), imag(i) {}   
 78 
 79 Complex::Complex(const Complex &c) : real(c.real), imag(c.imag) {}  
 80 
 81 double Complex::get_real() const {  
 82 
 83     return real;  
 84 
 85 }  
 86 
 87 double Complex::get_imag() const {  
 88 
 89     return imag;  
 90 
 91 }  
 92 
 93 Complex Complex::add(const Complex &c) const {  
 94 
 95     return Complex(this->real + c.real, this->imag + c.imag);  
 96 
 97 }  
 98 
 99 bool Complex::is_equal(const Complex &c) const {  
100 
101     return (real == c.real && imag == c.imag);  
102 
103 }  
104 
105 bool Complex::is_not_equal(const Complex &c) const {  
106 
107     return !is_equal(c);  
108 
109 }  
110 
111 void Complex::output() const {  
112 
113     std::cout << real << (imag >= 0 ? " + " : " - ") << fabs(imag) << "i";  
114 
115 }  
116 
117 double Complex::abs() const {  
118 
119     return std::sqrt(real * real + imag * imag);  
120 
121 }
122 
123 
124 
125 #include <iostream>  
126 
127 #include "Complex.h"  
128 
129 
130 
131 using std::cout;  
132 
133 using std::endl;  
134 
135 
136 
137 void test() {  
138 
139     cout << "类成员测试: " << endl;  
140 
141     cout << Complex::doc << endl;  
142 
143 
144 
145     cout << endl;  
146 
147 
148 
149     cout << "Complex对象测试: " << endl;  
150 
151     Complex c1; 
152 
153     Complex c2(3, -4); 
154 
155     const Complex c3(3.5); 
156 
157     Complex c4(c3); 
158 
159 
160 
161     cout << "c1 = "; c1.output(); cout << endl;  
162 
163     cout << "c2 = "; c2.output(); cout << endl;  
164 
165     cout << "c3 = "; c3.output(); cout << endl;  
166 
167     cout << "c4 = "; c4.output(); cout << endl;  
168 
169     cout << "c4.real = " << c4.get_real() << ", c4.imag = " << c4.get_imag() << endl;  
170 
171 
172 
173     cout << endl;  
174 
175 
176 
177     cout << "复数运算测试: " << endl;  
178 
179     cout << "abs(c2) = " << c2.abs() << endl;  
180 
181     c1 = c1.add(c2);  
182 
183     cout << "c1 += c2, c1 = "; c1.output(); cout << endl;  
184 
185     cout << "c1 == c2 : " << std::boolalpha << c1.is_equal(c2) << endl;  
186 
187     cout << "c1 != c3 : " << std::boolalpha << c1.is_not_equal(c3) << endl;  
188 
189     c4 = c2.add(c3);  
190 
191     cout << "c4 = c2 + c3, c4 = "; c4.output(); cout << endl;  
192 
193 }  
194 
195 
196 
197 int main() {  
198 
199     test();  
200 
201     return 0;  
202 
203 }

运行结果

 实验任务3

代码

#include <iostream>
#include <complex>

using std::cout;
using std::endl;
using std::boolalpha;
using std::complex;

void test() {
    cout << "标准库模板类comple测试: " << endl;
    complex<double> c1;
    complex<double> c2(3, -4);
    const complex<double> c3(3.5);
    complex<double> c4(c3);

    cout << "c1 = " << c1 << endl;
    cout << "c2 = " << c2 << endl;
    cout << "c3 = " << c3 << endl;
    cout << "c4 = " << c4 << endl;
    cout << "c4.real = " << c4.real() << ", c4.imag = " << c4.imag() << endl;
    cout << endl;

    cout << "复数运算测试: " << endl;
    cout << "abs(c2) = " << abs(c2) << endl;
    c1 += c2;
    cout << "c1 += c2, c1 = " << c1 << endl;
    cout << boolalpha;
    cout << "c1 == c2 : " << (c1 == c2) << endl;
    cout << "c1 != c3 : " << (c1 != c3) << endl;
    c4 = c2 + c3;
    cout << "c4 = c2 + c3, c4 = " << c4 << endl;
}

int main() {
    test();
}

运行结果

 实验任务4

代码

Fraction.h

 1 #pragma once
 2 #include <iostream>
 3 class Fraction
 4 {
 5 private:
 6     int up, down;
 7  
 8 public:
 9     Fraction(int x = 0, int y = 1);
10     Fraction(const Fraction& p);
11     ~Fraction();
12     friend void output(const Fraction &p);
13     friend Fraction add( Fraction p1,   Fraction p2);
14     friend Fraction sub( Fraction p1,  Fraction p2);
15     friend Fraction mul(const Fraction &p1, const Fraction &p2);
16     friend Fraction div(const Fraction &p1, const Fraction &p2);
17     int get_up();
18     int get_down();
19     Fraction negative();
20     static std::string doc;
21 };

Fraction.cpp

  1 #include "Fraction.h"
  2 #include <iostream>
  3 #include <algorithm>
  4 using namespace std;
  5 
  6 int ogcd(int a, int b)
  7 {
  8     if (a < b)
  9     {
 10         int c = b;
 11         b = a;
 12         a = c;
 13     }
 14     int r = a % b;
 15     while (r != 0)
 16     {
 17         a = b;
 18         b = r;
 19         r = a % b;
 20     }
 21     return b;
 22 }
 23 int igcd(int a, int b)
 24 {
 25     int sum1 = ogcd(a, b);
 26     return (a / sum1) * (b / sum1) * sum1;
 27 }
 28 std::string Fraction::doc = "Fraction类测试:\nFraction类 v 0.01版.\n目前仅支持分数对象的构造、输出、加/减/乘/除运算.";
 29 Fraction::Fraction(int x, int y)  {
 30  
 31     up = x;
 32     down = y;
 33 }
 34 Fraction::Fraction(const Fraction& p) :up{ p.up }, down{ p.down } {}
 35 Fraction::~Fraction() {}
 36 void output(const Fraction& p)
 37 {
 38     if (p.down == 0)
 39     {
 40         cout << "分母不能为0";
 41         return;
 42     }
 43     if (p.up == 0)
 44     {
 45         cout << "0";
 46         return;
 47     }
 48     if (p.down == 1)
 49     {
 50         cout << p.up;
 51         return;
 52     }
 53     int sum;
 54     if (p.up < 0)
 55     {
 56         sum = ogcd(-p.up, p.down);
 57         cout << "-" << -p.up / sum << "/" << p.down / sum;
 58         return;
 59     }
 60     else if (p.down < 0)
 61     {
 62         sum = ogcd(p.up, -p.down);
 63         cout << "-" << p.up / sum << "/" << -p.down / sum;
 64         return;
 65     }
 66     else
 67     {
 68         sum = ogcd(p.up, p.down);
 69         cout << p.up / sum << "/" << p.down / sum;
 70         return;
 71     }
 72 }
 73 Fraction add(Fraction p1, Fraction p2)
 74 {
 75     if (p1.down < 0)
 76     {
 77         p1.up = -p1.up;
 78         p1.down = -p1.down;
 79     }
 80     if (p2.down < 0)
 81     {
 82         p2.up = -p2.up;
 83         p2.down = -p2.down;
 84     }
 85     int sum2 = igcd(p1.down, p2.down);
 86     return Fraction(p1.up * (sum2 / p1.down) + p2.up * (sum2 / p2.down), sum2);
 87 }
 88 Fraction sub( Fraction p1,  Fraction p2)
 89 {
 90     if (p1.down < 0)
 91     {
 92         p1.up = -p1.up;
 93         p1.down = -p1.down;
 94     }
 95     if (p2.down < 0)
 96     {
 97         p2.up = -p2.up;
 98         p2.down = -p2.down;
 99     }
100     int sum2 = igcd(p1.down, p2.down);
101     return Fraction(p1.up * (sum2 / p1.down) - p2.up * (sum2 / p2.down), sum2);
102 }
103 Fraction mul(const Fraction& p1, const Fraction& p2)
104 {
105     return Fraction(p1.up * p2.up, p1.down * p2.down);
106 }
107 Fraction div(const Fraction& p1, const Fraction& p2)
108 {
109     return Fraction(p1.up * p2.down, p1.down * p2.up);
110 }
111 
112 int Fraction::get_up()
113 {
114         return up/ogcd(abs(up),abs(down));
115     
116  
117 }
118 int Fraction::get_down()
119 {
120         return down/ ogcd(abs(up), abs(down));
121   
122 }
123 Fraction Fraction::negative()
124 {
125     return Fraction(-up,down);
126 }

运行结果

 实验任务5

main.cpp 

 1 #include "C:\Users\DELL\Desktop\新建文件夹\account.h"
 2 #include <iostream>
 3 using namespace std;
 4 int main() {
 5 
 6     SavingsAccount sa0(1, 21325302, 0.015);
 7     SavingsAccount sa1(1, 58320212, 0.015);
 8   
 9     sa0.deposit(5, 5000);
10     sa1.deposit(25, 10000);
11     sa0.deposit(45, 5500);
12     sa1.withdraw(60, 4000);
13   
14     sa0.settle(90);
15     sa1.settle(90);
16     sa0.show();    cout << endl;
17     sa1.show();    cout << endl;
18     cout << "Total: " << SavingsAccount::getTotal() << endl;
19     return 0;
20 }

account.cpp

#include "account.h"
#include <cmath>
#include <iostream>
using namespace std;

double SavingsAccount::total = 0;

SavingsAccount::SavingsAccount(int date, int id, double rate)
        : id(id), balance(0), rate(rate), lastDate(date), accumulation(0) {
    cout << date << "\t#" << id << " is created" << endl;
}
void SavingsAccount::record(int date, double amount) {
    accumulation = accumulate(date);
    lastDate = date;
    amount = floor(amount * 100 + 0.5) / 100;    
    balance += amount;
    total += amount;
    cout << date << "\t#" << id << "\t" << amount << "\t" << balance << endl;
}
void SavingsAccount::deposit(int date, double amount) {
    record(date, amount);
}
void SavingsAccount::withdraw(int date, double amount) {
    if (amount > getBalance())
        cout << "Error: not enough money" << endl;
    else
        record(date, -amount);
}
void SavingsAccount::settle(int date) {
    double interest = accumulate(date) * rate / 365;    
    if (interest != 0)
        record(date, interest);
    accumulation = 0;
}
void SavingsAccount::show() const {
    cout << "#" << id << "\tBalance: " << balance;
}

account.h

 1 #ifndef __ACCOUNT_H__
 2 #define __ACCOUNT_H__
 3 class SavingsAccount { 
 4 private:
 5     int id;                
 6     double balance;        
 7     double rate;        
 8     int lastDate;        
 9     double accumulation;    
10     static double total;    
11   
12     void record(int date, double amount);
13   
14     double accumulate(int date) const {
15         return accumulation + balance * (date - lastDate);
16     }
17 public:
18    
19     SavingsAccount(int date, int id, double rate);
20     int getId() const { return id; }
21     double getBalance() const { return balance; }
22     double getRate() const { return rate; }
23     static double getTotal() { return total; }
24     void deposit(int date, double amount);         
25     void withdraw(int date, double amount);     
26     
27     void settle(int date);
28    
29     void show() const;
30 };
31 #endif

 

posted @ 2024-10-29 20:51  臣子民  阅读(17)  评论(0编辑  收藏  举报