构造函数
1.为什么需要构造函数?
因为要创建对象,类要提供一种或几种成员函数来控制其对象初始化的过程,这种特殊的成员函数就是构造函数
2.构造函数的定义
- 构造函数的名字和类的名相同
- 构造函数没有返回值
- 构造函数不能被声明成const的
- 直到函数完成初始化过程,类内的const对象才真正获得“常量属性”
- 不同的构造函数必须在形参的数量或者数据类型上有所不同
3. 构造函数的类型
编译器对构造函数的处理
- 默认构造函数,类默认提供,但是如果提供了有参构造函数,编译器就不会再提供默认构造函数,但仍然会提供拷贝构造函数
- 如果自行提供了拷贝构造函数,则编译器不会提供任何构造函数
3.编译器提供的拷贝函数是浅拷贝(新对象没有自己的存储空间,只是指向了初始化对象的地址)
#include <iostream>
#include<string>
using namespace::std;
class People {
private: string name;
int age;
public:
//默认构造函数
//People()=default;
People() {
cout << "默认构造函数" << endl;
};
//有参构造函数
People(string name, int age) {
cout<<"有参构造函数"<<endl;
this->name = name;
this->age = age;
}
//拷贝构造函数,传入的参数一定是一个同类型的引用,不能传入值,会调用拷贝
//构造函数,因为我们在写拷贝构造函数,所以会报错
People(const People& p) {
cout<<"拷贝构造函数"<<endl;
this->name = p.name;
this->age = p.age;
}
//析构函数
~People() {
cout << "调用析构函数" << endl;
}
};
void test() {
People();
People p= People("张三",18);
People cy1 = p;
People cy2(p);
}
int main() {
test();
system("pause");
return 0;
}
编译器的优化功能
//示例代码 对象分配到栈上
默认构造函数创建一个对象,后面没有用到,立即析构掉 People ()创建一个没有名字对象,立即释放掉
有参构造函数创建对象,由于要作为后边两个对象的拷贝构造实参所以要等到调用结束后才会被析构掉
4 拷贝构造函数的调用时机
- 函数内,用一个已经有的对象,去初始化另一个对象
- 函数形参传入一个对象的值,是值传递,不是引用传递
- 函数的返回值是一个对象的值时
//情况1
void test1() {
People p;
People cy1(p);
People cy2 = p;
}
int main() {
test1();
system("pause");
return 0;
}
默认构造函数
拷贝构造函数
拷贝构造函数
调用析构函数
调用析构函数
调用析构函数
请按任意键继续. . .
//情况2
void test2(People p) {
cout<<"情况2"<<endl;
}
int main() {
test2(*(new People()));
system("pause");
return 0;
}
默认构造函数
拷贝构造函数
情况2
调用析构函数
请按任意键继续. .
People test3() {
return *(new People());
}
int main() {
test3();
system("pause");
return 0;
}
默认构造函数
拷贝构造函数
调用析构函数
请按任意键继续. .
5.构造函数的列表初始化
#include <iostream>
#include<string>
using namespace std;
class People {
private:
string name;
int age;
public:
People(string n, int a) :name(n), age(a) {};
};