以前我在学习C++的时候总是对类的各种构造函数搞不明白,今天来细细梳理一下qwq。
(我是一只萌新)
构造函数的作用:
要和构造函数深入交流,首先就要明白它有什么用,可以干什么。构造函数
是一个在定义一个 对象 时,编译器会自动调用的函数, 这个玩意一般用来
进行"初始化"工作,也就是给对象内部的数据成员进行初始化。
构造函数的特点:
<1> 在创建新对象的时候会自动调用.
<2>构造函数的函数名是和类名一样的.
<3>构造函数没有返回类型(这个特点看着真别扭)
<4>可以存在多个构造函数(即函数重载形式)
构造函数的种类:
(1) 默认构造函数
(2) 自定义的构造函数
(3) 拷贝构造函数
(4)赋值构造函数
(5)析构函数
OK了解了基本的信息之后我们开始来深入了解一下这几种构造函数:
默认构造函数
<1> 由编译器自己生成的: 合成默认构造函数
当没有手动定义默认构造函数时,编译器就会自动为这个类定义一个
构造函数。
它的作用:
没什么卵用,无实际意义,连初始化都做不了。
<2> 自定义的默认构造函数()
如果某数据成员使用类内初始值,同时又在构造函数中进行了初始化,
那么以构造函数中的初始化为准。
有什么用:
1.初始化成员变量,它可以按照你的想法为对象中的成员变量进行初始化,
而不是像使用编译器自动生成的不确定初始值。如:
class MyClass{
private:
int num;
std::string str;
publlic:
MyClass(){
num = 0;
str = "default";
}
};
在这段代码中,自定义的默认构造函数将变量 num 初始化为了 0,
将 str 初始化为了 "default" ,确保了对象在创建时就处于一个明确的
状态。
2.执行特定的逻辑
可以在构造函数中按照你的想法执行一些逻辑操作,比如打开文件建立数据库连接等。
如:
class FileHandler {
private:
std::ifstream file;
public:
FileHandler() {
file.open("data.txt");
f (!file.is_open()) {
// 处理文件打开失败的情况
}
}
};
3.提高代码的可读性和可维护性
自定义默认构造函数可以使代码更清晰的表达对象的初始化意图,
让其他开发者更加容易理解代码的逻辑,当需要修改对象的初始化
方式时,只需要在构造函数中进行修改,然后就不用在多个地方进
行分散的初始化操作了。
拷贝构造函数
拷贝构造函数的声明格式: 类名(const 类名&)
什么时候调用拷贝构造函数:
<1>使用一个已经存在的对象初始化另一个新对象时,如:
class MyClass {
public:
MyClass(const MyClass& other) {
// 拷贝构造函数的实现
}
};
MyClass obj1;
MyClass obj2 = obj1; // 调用拷贝构造函数
MyClass obj3(obj1); // 也会调用拷贝构造函数
<2>当对象作为函数参数按值传递时,会调用拷贝构造函数来创建函数参数的副本,如:
void func(MyClass obj) {
// 函数体
}
MyClass obj1;
func(obj1); // 调用拷贝构造函数将 obj1 拷贝到函数参数 obj 中
//这里建议传值的时候使用引用QwQ
<3>当函数返回一个对象时,可能会调用拷贝构造函数来创建返回值的副本,如:
MyClass func(){
MyClass obj;
return obj;
}
MyClass obj2 =func(); //可能调用拷贝构造函数
// C++中是可以通过移动构造函数和右值引用来优化对象创建的,我们应该注意减少不必 要的拷贝操作
赋值构造函数:
本质:说是构造函数,其实就是"="运算符的重载
//运算符重载就是一种允许程序猿们为自定义的类类型进行重新定义已有运算符的行为,
//让运算符能够按照你的想法去处理自定义的类型对象
声明方式: 类名& operator=(const 类名&) ;
用处:
<1>允许你将一个已经存在对象的值赋给另一个同类型的对象。例如:
class MyClass {
public:
int value;
MyClass& operator=(const MyClass& other) {
value = other.value;
return *this;
}
};
MyClass obj1;
obj1.value = 10;
MyClass obj2;
obj2 = obj1; // 调用赋值构造函数
<2> 如果对象中有动态分配的资源(如指针指向的内存),复制构造函数可以确保在赋值过程中正确
的处理资源的复制,释放和重新分配,防止资源泄露和重复释放等问题。如:
class ResourceHolder {
private:
int* data;
public:
ResourceHolder() : data(new int[10]) {}
~ResourceHolder() {
delete[] data;
}
ResourceHolder& operator=(const ResourceHolder& other) {
if (this!= &other) {
delete[] data;
data = new int[10];
std::copy(other.data, other.data + 10, data);
}
return *this;
}
};
析构函数
析构函数一般放在类的public中,且不能主动调用析构函数
作用:在对象销毁之前做清理工作(释放资源),如上面的内存释放。
~ResourceHolder() {
delete[] data;
}
以上就是小柒梳理的构造函数了,如有不对的地方还望指出@w@