构造函数定义及调用
1)C++中的类可以定义与类名相同的特殊成员函数,这种与类名相同的成员函数叫做构造函数;
2)构造函数在定义时可以有参数;
3)没有任何返回类型的声明;
构造函数定义及调用
1)C++中的类可以定义一个特殊的成员函数清理对象,这个特殊的成员函数叫析构函数,语法:~ClassName();
2)析构函数没有参数也没有任何返回类型的声明;
3)析构函数在对象销毁时自动被调用;
默认构造函数
二个特殊的构造函数
1)默认无参构造函数:当类中没有定义构造函数时,编译器默认提供一个无参构造函数,并且其函数体为空。
2)默认拷贝构造函数:当类中没有定义拷贝构造函数时,编译器默认提供一个默认拷贝构造函数,简单的进行成员变量的值复制。
构造函数调用规则
1)当类中没定义任何构造函数时,C++编译器会提供默认无参构造函数和默认拷贝构造函数。
2)当类中定义了拷贝构造函数时,C++编译器不会提供无参数构造函数。
3) 当类中定义了任意的非拷贝构造函数(即:当类中提供了有参构造函数或无参构造函数),C++编译器不会提供默认无参构造函数。
4)默认拷贝构造函数进行的是浅拷贝。
构造函数的分类及调用
我们来看如下代码:
class Test { private: int a, b; public: Test() {} // 无参数构造函数 Test(int a, int b) {} // 带参数的构造函数 Test(const Test &obj) {} // 赋值构造函数 public: void init(int _a, int _b) { a = _a; b = _b; } };
1)无参数构造函数:调用方法如下
Test t1, t2; Test t1 = Test(); // 这样才是调用默认构造函数,这时必须带有括号
2)带参数构造函数
Test t1(20, 10); // 括号法: C++编译器默认调用有参构造函数 Test t2 = (20, 10); // 等号法: C++编译器默认调用有参构造函数 Test t3 = Test(20, 10); // 直接调用构造构造函数法: 程序员手工调用构造函数产生了一个对象
3)赋值(拷贝)构造函数:下面介绍赋值构造函数的三种调用场景(调用时机)。
a. 用对象1初始化对象2
class Test { public: Test() { cout << "我是构造函数,自动被调用了" << endl; } Test(int _a) : a(_a) {} Test(const Test &obj2) { cout << "我也是构造函数,我是通过另外一个对象obj2,来初始化我自己" << endl; } ~Test() { cout<<"我是析构函数,自动被调用了"<<endl; } private: int a; }; int main() { Test a1; Test a2 = a1; // 用 a1 初始化 a2 Test a3(a1); // 这样写也是用 a1 初始化 a3 return 0; }
b. 实参变量初始化形参变量
class Location { public: Location(int x = 0, int y = 0) : X(x), Y(y) { cout << "Constructor Object.\n"; } Location(const Location &p) : X(p.X), Y(p.Y) { cout << "Copy_constructor called." << endl; } ~Location() { cout << X << "," << Y << " Object destroyed." << endl; } int GetX () { return X; } int GetY () { return Y; } private: int X, Y; }; void f(Location p) { cout << "Funtion:" << p.GetX() << "," << p.GetY() << endl; } int main() { Location A(1, 2); f(A); // 调用f会构造一个临时对象p,此时会调用拷贝构造函数 return 0; }
c. 函数返回匿名对象,会在栈上面通过拷贝构造函数产生一个临时对象(一般会被优化),那之后就取决于程序员怎么来接收这个匿名对象。
class Location { public: Location(int x = 0, int y = 0) : X(x), Y(y) { cout << "Constructor Object.\n"; } Location(const Location &p) : X(p.X), Y(p.Y) { cout << "Copy_constructor called." << endl; } ~Location() { cout << X << "," << Y << " Object destroyed." << endl; } int GetX () { return X; } int GetY () { return Y; } private: int X, Y; }; void f(Location p) { cout << "Funtion:" << p.GetX() << "," << p.GetY() << endl; } /* * 当函数需要返回一个对象,他会在栈中创建一个临时对象,存储函数的返回值。 * 这个临时对象也是匿名对象,构造它时会调用拷贝构造函数,用A来初始化这个匿名对象。 * 然后函数调用结束,A被销毁. * 但是这个临时对象的构造一般会被编译器优化掉,所以自己测试的时候一般不会调用拷贝构造函数了。 */ Location g() { Location A(1, 2); return A; } int main() { Location B; B = g(); // 若返回的匿名对象,赋值给另外一个同类型的对象,那么匿名对象会被析构 Location C = g(); // 若返回的匿名对象,来初始化另外一个同类型的对象,那么匿名对象会直接转成新的对象 return 0; }
原文:https://www.cnblogs.com/yanghh/p/12980542.html