构造函数定义及调用
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