C++面向对象练习(一)—— 各种函数执行顺序

本文最后更新于:2020年4月14日 上午

概览:C++面向对象练习:构造函数、拷贝构造函数、重载赋值运算符以及析构函数的执行顺序。


代码全部运行于VS2019

博客后续会持续更新补充。

各个函数执行顺序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
class Dog
{
public:
Dog()
{
cout << "默认构造函数" << endl;
}

Dog(int age) :age(age)
{
cout << "有参构造函数" << endl;
}

Dog(const Dog& dog) :age(dog.age)
{
cout << "拷贝构造函数" << endl;
}

Dog& operator=(const Dog& dog)
{
cout << "拷贝赋值运算" << endl;
if(this == &dog)//自赋值
return *this;

this->age = dog.age;
return *this;
}

~Dog()
{
cout << "析构函数" << endl;
}

void show()
{
cout << "-- "<<this->age <<" --"<< endl;
}

private:
int age;
};

void test0()
{
cout << "函数test0()开始执行" << endl;
Dog d0;
cout << "函数test0()结束执行" << endl;
}

void test1(Dog dd)
{
cout << "函数test1()开始执行" << endl;
dd.show();
cout << "函数test1()结束执行" << endl;
}

Dog test2(Dog& dd)
{
cout << "函数test2()开始执行" << endl;
Dog tmp = dd;
tmp.show();
cout << "函数test2()结束执行" << endl;
return tmp;
}

int main()
{
cout << "主函数main()开始执行" << endl;
test0();

Dog d1(12);

Dog d2 = d1;

Dog d3;

d3 = d1;

test1(d3);

Dog d4;

d4 = test2(d1);

cout << "主函数main()结束执行" << endl;

return 0;
}

执行结果如下:

  • 主函数main()开始执行

  • 函数test0()开始执行

  • 默认构造函数

  • 函数test0()结束执行

  • 析构函数

  • 有参构造函数

  • 拷贝构造函数

  • 默认构造函数

  • 拷贝赋值运算

  • 拷贝构造函数

  • 函数test1()开始执行

  • – 12 –

  • 函数test1()结束执行

  • 析构函数

  • 默认构造函数

  • 函数test2()开始执行

  • 拷贝构造函数

  • – 12 –

  • 函数test2()结束执行

  • 拷贝构造函数

  • 析构函数

  • 拷贝赋值运算

  • 主函数main()结束执行

  • 析构函数

  • 析构函数

  • 析构函数

  • 析构函数

d4 = test2(d1)在函数值返回时注意!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Dog test3()
{
cout << "函数test3()开始执行" << endl;
Dog tmp(10);
cout << "函数test3()结束执行" << endl;
return tmp;
}

int main()
{
cout << "主函数main()开始执行" << endl;

Dog d5 = test3();

cout << "--------" << endl;

test3();

cout << "主函数main()结束执行" << endl;

return 0;
}

结果为:

  • 主函数main()开始执行
  • 函数test3()开始执行
  • 有参构造函数
  • 函数test3()结束执行
  • 拷贝构造函数
  • 析构函数
  • --------
  • 函数test3()开始执行
  • 有参构造函数
  • 函数test3()结束执行
  • 拷贝构造函数
  • 析构函数
  • 析构函数
  • 主函数main()结束执行
  • 析构函数

当函数返回一个对象的时候,所作的操作为匿名对象 = return tmp,这样就会执行拷贝构造函数,然后tmp析构。

而若是函数返回的匿名对象没有值进行接受的话,匿名对象会立刻进行析构。而若是有值进行接受的话,匿名对象就会转正,不会触发任何函数。

C++面向对象练习

试定义一个处理学生信息的类Student。该类包含学号、成绩和姓名等数据成员( 学号不能相同)以及
若干成员函数,另外定义全局函数max),返回n个学生成绩最高者。

具体要求如下:

(1)私有数据成员

int num,score; num存放学号,score 存放成绩

char name[9]; name 存放学生的姓名

(2)公有成员函数

构造函数:将学号、成绩设置为0,姓名设置为空

void Set(int id,char *na,int sc );为数据成员赋值。

int get_ score();返 回学生成绩。

void print();输出学生的学号、姓名和成绩。

(3) Student max(Student *,int n);全局函数,求得并返回s所指向的n个学生中成绩最高者。

int check_num(Student str[],int n,int num);检查学号是否已经在str中存在返回1,否则返回0。

(4)在主函数中完成对该类的测试,主函数中定义一个长度为3的Student类的对象数组s,依次键入学号、成绩、姓名;注意,在输入每-一个学生的信息后,要判断所输入的学号是否已存在,如果存在,则要求重新输入该学生的信息。最后调用全局函数max(,得到成绩最高的学生信息并输出。

参考链接: C++面向对象程序设计50道编程题(第21题)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*测试环境: VS2019*/
#include <iostream>

using namespace std;

class Student
{
public:
Student();
~Student();

void Set(int id, char* na, int sc); //为数据成员赋值
int get_score(); //返回学生成绩
int get_num(); //返回学生学号
void print(); //输出学生的学号、姓名、成绩

private:
int num; //学号
int score; //成绩
char name[9]; //姓名
};

Student max(Student*, int n); //求得并返回n个学生中成绩最高的
int check_num(Student stu[], int n,int num);//检查学号是否已经在stu中

int main()
{
Student stu[3];
int input_num;
int input_score;
char input_name[9];
int i = 0;
while(1)
{
cout << "请输入学生的学号" << endl;
cin >> input_num;
if (check_num(stu, i, input_num) == 1)
{
cout << "已经存在,请重新输入" << endl;
continue;
}

cout << "请输入学生的成绩" << endl;
cin >> input_score;

cout << "请输入学生的姓名" << endl;
cin >> input_name;

stu[i].Set(input_num, input_name, input_score);

cout << "信息录入成功" << endl;

i++;

if (i >= 3) break;
}

cout << "学生信息如下:" << endl;
for (i = 0; i < 3; i++)
{
stu[i].print();
}

cout << "成绩最高的学生信息如下:" << endl;
max(stu, 3).print();

return 0;
}

Student::Student()
{
this->num = 0;
this->score = 0;
strcpy_s(this->name,"");
}

Student::~Student()
{

}

void Student::Set(int id, char* na, int sc)
{
this->num = id;
this->score = sc;
strcpy_s(this->name, na);
}

int Student::get_score()
{
return this->score;
}

int Student::get_num()
{
return this->num;
}

void Student::print()
{
cout << "Name: " << this->name << ": id:" << this->num
<< ", score: " << this->score << endl;
}

Student max(Student* stu, int n)
{
int max = 0;
int max_score = stu[0].get_score();

for (int i = 1; i < n; i++)
{
if (max_score < stu[i].get_score())
{
max_score = stu[i].get_score();
max = i;
}
}
return stu[max];
}

int check_num(Student stu[], int n, int num)
{
for (int i = 0; i < n; i++)
{
if (stu[i].get_num() == num)
{
return 1;
}
}
return 0;
}