六大默认成员函数
默认成员函数的概念:如果类中未显式定义,编译器会自动生成的成员函数,即为默认成员函数。
一、构造函数
概念:
构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,以保证每个成员对象都有一个合适的初始值,并且在对象的整个生命周期内只(由编译器)调用一次。
特点:
1.函数名与类名相同。
2.无返回值。
3.对象实例化时编译器自动调用对应的构造函数。
4.构造函数可以重载。
5.如果类中没有显式写构造函数,则编译器会自动生成一个无参的构造函数,如果显式写了构造函数,编译器则不会自动生成构造函数。
6.全缺省的构造函数、无参的构造函数、和编译器默认生成的构造函数都可作为编译器默认的构造函数,但只能同时存在一个。
class Date
{
public:
//构造函数的重载
Date()
{
}
Date(int year,int month,int day)
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;//创建并通过无参构造函数初始化对象时,无需加括号,不然变成了函数声明
Date d2(2024,4,14);//调用含参构造
return 0;
}
注意:在C++中,定义了构造函数会自动调用,但是在实际中vs是不会调用构造函数的,所以C++11打了一个补丁就是可以在声明类的成员的时候可以增加一个缺省值,在编译的过程中,就会根据成员变量的缺省值来对对象进行初始化。
例:
class Date
{
int _year = 2000;
int _month = 1;
int _day = 1;
};
int main()
{
Date d;
return 0;
}
在没有显式写构造函数的时候,在对类中的成员声明时就会根据参数的缺省值进行初始化。
二、析构函数
功能:析构函数的工作类似于destroy,但是对于内置类型一般不需要调用析构函数,编译器会自动销毁,所以一般需要用析构函数的是在堆上开辟出来的空间。
特点:
1.析构函数名是在类名前加上字符~。
2.无参数无返回值类型。
3.一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。(注意:析构函数不能重载)
4.对象生命周期结束时,C++编译系统自动调用析构函数。
#include<iostream>
using namespace std;
class Time
{
public:
~Time()
{
cout << "~Time()" << endl;
}
private:
int _time;
};
class Date
{
public:
~Date()
{
cout << "~Date()" << endl;
}
private:
int _year;
int _month;
int _day;
Time t;
};
int main()
{
Date st;
return 0;
}
运行结果:
三、拷贝构造函数
概念:拷贝构造函数,又称复制构造函数,是一种特殊的构造函数,它由编译器调用来完成一些基于同一类的其他对象的构建及初始化。
特征:
1、拷贝构造函数是构造函数的一种重载形式。
2、其形参必须是引用,但并不限制为const,一般普遍的会加上const限制。
注意:如果使用传值传参的方式进行拷贝构造,在传值的过程中实参需要拷贝一份数据给形参,这个过程需要调用拷贝构造。形成层层传值引发对象的拷贝的递归(有递无归)调用。
3、如果没有显式定义拷贝构造函数则编译器会自动生成一个默认的拷贝构造函数,并且在调用的时候会成功,但是需要注意的是这里编译器生成的拷贝构造函数是浅拷贝,而不是深拷贝。
深拷贝和浅拷贝的区别:
1、浅拷贝是按位拷贝对象,它会创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值;如果属性是内存地址(引用类型),拷贝的就是内存地址 ,因此如果其中一个对象改变了这个地址,就会影响到另一个对象。
2、深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。
四、总结
1、默认构造函数(Default Constructor):如果我们没有定义任何构造函数,编译器将会生成一个默认构造函数。默认构造函数不接受任何参数,并且执行成员变量的默认初始化。在很多情况下,这可能是合适的,但如果类的成员需要特定的初始化值,可能需要显式定义构造函数。
2、析构函数(Destructor):如果我们没有提供析构函数,编译器会生成一个默认的析构函数。默认析构函数会释放对象所占用的内存,如果对象包含有指针成员,可能不会正确地释放内存或执行其他必要的清理工作。如果类需要在对象销毁时执行特定操作,比如释放资源或者清理其他状态,就需要显式定义析构函数。
3、拷贝构造函数(Copy Constructor):如果我们没有定义拷贝构造函数,编译器会生成一个默认的拷贝构造函数。默认拷贝构造函数会执行浅拷贝(shallow copy),即对于指针成员只复制指针而不复制指针所指向的对象。这可能导致浅拷贝问题,即多个对象共享同一块内存。如果类含有指针成员,或者需要进行深拷贝或其他特殊处理,就需要显式定义拷贝构造函数