复制
【C++】类与对象篇二
1. 类的6个默认成员函数
(1) . 默认成员函数:用户没有显式实现,编译器会生成的成员函数称为默认成员函数;用户显式定义对应成员函数,编译器将不再生成对应默认成员函数;
(2) . “ 任何类 ” 在什么都不写时,编译器会自动生成以下6个默认成员
函数。
2. 构造函数
(1) . 构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时(对象的实例化)由编译器自动调用,并且在对象整个生命周期内只调用一次。
(2) . 如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义编译器将不再生成无参默认构造函数(可手动生成无参构造函数,因为构造函数可以重载),则不能实例化无参对象。
(3) . 构造函数的主要任务并不是开空间创建对象,而是初始化对象。
(4) . 构造函数的特征:
- 函数名与类名相同。
- 无返回值。
- 对象实例化时编译器自动调用对应的构造函数。
- 构造函数可以重载。
classDate
{
public:
// 1.无参构造函数
Date()
{}
// 2.带参构造函数
Date(intyear, intmonth, intday) {
_year=year;
_month=month;
_day=day;
}
private:
int_year;
int_month;
int_day;
};
voidTestDate()
{
Date d1; // 调用无参构造函数
//Date d1(); // 不可以这样写,会跟**函数声明**有点冲突,编译器不好识别
Date d2(2015, 1, 1); // 调用带参的构造函数
//
> 注意:如果通过无参构造函数创建对象时,对象后面不用跟括号,否则就成了函数声明
// 以下代码的函数:声明了d3函数,该函数无参,返回一个日期类型的对象
// warning C4930: “Date d3(void)”: 未调用原型函数(是否是有意用变量定义的?)
Date d3();
}
(5) . 默认构造函数的作用:
C++把类型分成内置类型(基本类型)和自定义类型。内置类型就是语言提供的数据类型,如:int/char…,自定义类型就是我们使用class/struct/union等自己定义的类型,编译器生成默认的构造函数会对 “ 自定类型成员 ” 调用的它的默认成员函数。而对于 “ 基本类型 ” 是否会调用默认成员函数初始化,取决于编译器,我们一般认为不会,所以:
C++11 中针对内置类型成员不初始化的缺陷,又打了补丁,即:内置类型成员变量在类中声明时可以给默认值,间接实现初始化基本类型
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/a502c525ccd948169087b50dd34f034c.png
classDate {
private:
// 基本类型(内置类型)
int_year=1970;//声明时给默认值
int_month=1;
int_day=1;
};
(6) .
无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。
注意:无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数,都可以认为是默认构造函数。
即:不用传参数就可以调用
一旦写了无参的构造函数或全缺省的构造函数,编译器就不会生成默认构造函数
下面代码会报错:违反了默认构造函数只能有一个这个条件。
class Date {
public:
Date()
{
_year = 1900;
_month = 1;
_day = 1;
}
Date(int year = 1900, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;
return 0;
}
3. 析构函数
(1) . 析构函数:与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由编译器完成的。而对象在销毁时会自动调用析构函数,完成对象中资源的 “ 清理工作 ”。
(2) . 析构函数的特性:
- 析构函数名是在类名前加上字符 ~。
- 无参数无返回值类型。
- 一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。注意:析构不支持重载
- 对象生命周期结束时,C++编译系统系统自动调用析构函数。
(3) . 如果类中没有申请资源(如:malloc等申请堆上的空间资源)时,析构函数可以不写,直接使用编译器生成的默认析构函数,有资源申请时,一定要写,否则会造成资源泄漏
4. 拷贝(复制)构造函数
(1) . 拷贝构造函数 :只有单个形参,该形参是对本类类型对象的引用(一般常用const修饰),在用已存在的类类型对象创建新对象时由编译器自动调用。即创建一个与已存在对象一某一样的新对象
(2) . 拷贝构造函数的特征:
- 拷贝构造函数是构造函数的一个重载形式。
- 拷贝构造函数的参数只有一个且必须是类类型对象的引用,使用传值方式编译器直接报错,因为会引发无穷递归调用
(3) . 若未显式定义,编译器会生成默认的拷贝构造函数。默认的拷贝构造函数对象内存存储按字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝。
注意:1 . 在编译器生成的默认拷贝构造函数中,内置类型是按照字节方式直接拷贝的,而自定 义类型是调用其拷贝构造函数完成拷贝的。
2 . 类中如果没有涉及资源申请时,拷贝构造函数是否写都可以;一旦涉及到资源申请时,则拷贝构造函数是一定要写的,否则就是浅拷贝。
(4) . 拷贝构造函数典型调用场景:
1 .使用已存在对象创建新对象
2. 函数参数类型为类类型对象
3.函数返回值类型为类类型对象
为了提高程序效率,一般对象传参时,尽量使用引用类型,返回时根据实际场景,能用引用尽量使用引用。
class Date
{
public:
Date(int year, int minute, int day)
{
cout << "Date(int,int,int):" << this << endl;
}
Date(const Date& d)
{
cout << "Date(const Date& d):" << this << endl;
}
~Date()
{
cout << "~Date();" << this << endl;
}
private:
int _year;
int _month;
int _day;
};
Date Test(Date d)//函数参数类型为类类型对象
{
Date temp(d);
return temp;//函数返回值类型为类类型对象
}
int main()
{
Date d1(2024,8,21);
Test(d1);
return 0;
}
运行结果:
深浅拷贝的补充: