来看一段简单的代码
1 #include <iostream.h>
2 class human
3 {
4 public:
5 human(){ human_num++;}; //默认构造函数
6 static int human_num;
7 ~human()
8 {
9 human_num--; //析构函数
10 print();
11 }
12 void print()
13 {
14 cout<<"human num is: "<<human_num<<endl;
15 }
16 protected:
17 private:
18 };
19 int human::human_num = 0;
20
21 human f1(human x)
22 {
23 x.print();
24 return x;
25 }
26 int main(int argc, char* argv[])
27 {
28 human h1;
29 h1.print();
30 human h2 = f1(h1);
31 h2.print();
32 return 0;
33 }
答案输出为
1
1
0
0
-1
-2
让我们分析一下:
首先,静态变量hum_num创建,值是0. 当f1被定义时,调用human的构造函数,hum_num++(1)。h1.print()输出为1
重点开一看 human h2 = f1 (h1);
f1(h1)调用的是f1函数,因为f1函数的参数是值传递,那么这里发生human使用了拷贝构造函数对x进行构造,而没有使用human默认的构造函数。所以hum_num值不发生改变。
x.print()输出1
return x; 这一句返回一个局部变量,然后赋值给f2,这里使用了f2的拷贝构造函数,也没有使用默认构造函数。
在退出f1时,x调用析构函数,hum_num--(0)输出0
h2.print()输出0
当main退出时,h2调用析构函数,hum_num--(-1)输出-1
h1调用析构函数,hum_num--(-2)输出-2
那么,如果我们加上拷贝构造函数会怎么样呢?
代码
1 #include <iostream.h>
2 class human
3 {
4 public:
5 human(){
6 human_num++;
7 cout<<"default constructor : "<<human_num<<endl;
8 };
9 static int human_num;
10 ~human()
11 {
12 human_num--;
13 cout<<"destructor : "<<human_num<<endl;
14 }
15
16 human (const human &other)
17 {
18 human_num++;
19 cout<<"copy constructor : "<<human_num<<endl;
20 }
21
22 void print()
23 {
24 cout<<"print function : "<<human_num<<endl;
25 }
26 protected:
27 private:
28 };
29 int human::human_num = 0;
30
31 human f1(human x)
32 {
33 x.print();
34 return x;
35 }
36 int main(int argc, char* argv[])
37 {
38 human h1;
39 h1.print();
40 human h2 = f1(h1);
41 h2.print();
42 return 0;
43 }
Output:
default constructor : 1
print function : 1
copy constructor : 2
print function : 2
copy constructor : 3
destructor : 2
print function : 2
destructor : 1
destructor : 0
那么赋值函数该怎么写呢?
human& operator = (const human &other) //返回值是human的引用,应该是为了操作链吧,比如f1(one = two)这种 { }