【C++】类与对象篇二

复制

1. 类的6个默认成员函数

(1) . 默认成员函数:用户没有显式实现,编译器会生成的成员函数称为默认成员函数;用户显式定义对应成员函数,编译器将不再生成对应默认成员函数;
(2) . “ 任何类 ” 在什么都不写时,编译器会自动生成以下6个默认成员

函数。
在这里插入图片描述

2. 构造函数

(1) . 构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时(对象的实例化)由编译器自动调用,并且在对象整个生命周期内只调用一次。
(2) . 如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义编译器将不再生成无参默认构造函数(可手动生成无参构造函数,因为构造函数可以重载),则不能实例化无参对象
(3) . 构造函数的主要任务并不是开空间创建对象,而是初始化对象。
(4) . 构造函数的特征:

  1. 函数名与类名相同。
  2. 无返回值。
  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;
};

在这里插入图片描述
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/d7b2ff8896984a80b82f22ee53b265d6.png

(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) . 析构函数的特性:

  1. 析构函数名是在类名前加上字符 ~
  2. 无参数无返回值类型
  3. 一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。注意:析构不支持重载
  4. 对象生命周期结束时,C++编译系统系统自动调用析构函数。

在这里插入图片描述

(3) . 如果类中没有申请资源(如:malloc等申请堆上的空间资源)时,析构函数可以不写,直接使用编译器生成的默认析构函数,有资源申请时,一定要写,否则会造成资源泄漏
在这里插入图片描述

4. 拷贝(复制)构造函数

(1) . 拷贝构造函数 :只有单个形参,该形参是对本类类型对象的引用(一般常用const修饰),在用已存在的类类型对象创建新对象时由编译器自动调用。即创建一个与已存在对象一某一样的新对象
(2) . 拷贝构造函数的特征

  1. 拷贝构造函数是构造函数的一个重载形式。
  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;
}

运行结果:
在这里插入图片描述
在这里插入图片描述

深浅拷贝的补充:
在这里插入图片描述

评论 69
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值