构造函数
构造函数可以使对象在创建之初就具备了自定义的属性,而不是每次创建的对象都是相同的数据
构造函数用来创建一个对象,当我们在一个类中不写构造函数时,编译器会自动添加一个没有参数、函数内容的空的构造函数
如果手动编写任意一个构造函数,编译器将不会再添加任何构造函数
构造函数是一种特殊的函数,不写返回值类型,因为返回值类型都是创建的对象本身。函数名称与类名完全一致
构造函数支持函数重载与默认值
//这里还是以手机为例
#include <iostream>
using namespace std;
class MobilePhone
{
private:
string brand = "山寨";
string model = "8848";
int weight = 666;
public:
// 编译器自动添加一个无参构造函数
MobilePhone(){}
// 重载的构造函数
MobilePhone(string b,string m,int w)
{
brand = b;
model = m;
weight = w;
}
void show()
{
cout << brand << endl;
cout << model << endl;
cout << weight << endl;
}
};
int main()
{
MobilePhone mp1;
mp1.show();
MobilePhone* mp2 = new MobilePhone;
mp2->show();
delete mp2;
// 调用三个参数的构造函数
MobilePhone mp3("华为","p50 pro",222);
mp3.show();
MobilePhone* mp4 = new MobilePhone("三星","S22 Ultra",199);
mp4->show();
delete mp4;
return 0;
}
构造初始化列表
构造初始化列表实在构造函数中给成员变量赋值的简便写法
例:
MobliePhone(string b, string m, int w)
{
brand = b;
model = m;
weight = w;
}
也可以这样写
public:
MobilePhone(string b,string m,int w)
:string(b),model(m),weight(w){} // 构造初始化列表
这两种写法基本相同区别在于:
1、对常量成员变量赋值时
2、执行时机
拷贝构造函数
当我们在一个类中不写拷贝构造函数时,编译器会自动添加一个拷贝构造函数来支持对象拷贝功能,拷贝构造函数创建出的对象仅仅是与原对象数据相同,对象之间相互独立
拷贝构造函数也是一个函数重载
MobilePhone mp3("华为", "P50 pro", 200);
mp3.show();
MobilePhone mp4(mp3);//拷贝构造函数
mp4.show(); //mp3和mp4是两个对象,数据相互独立
浅拷贝与深拷贝
浅拷贝
当一个类中成员变量出现指针类型时,默认的拷贝构造函数会出现浅拷贝
深拷贝
深拷贝为了解决浅拷贝资源不独占问题,在每次赋值时单独开辟一个内存空间,让当前指针独享
class Dog
{
private:
char* name;
public:
Dog(char* n)
{
name = new char[20];
strcpy(name,n);
}
Dog(const Dog& d)
{
name = new char[20]; // 开启一个堆内存区域
strcpy(name,d.name); // 拷贝内容
}
Dog(/* args */){}
~Dog()
{
delete name;
}
};