学习C/C++系列(9)C++类的6个默认函数

​ C++的六个默认成员函数。

​ 如果一个类中什么成员都没有,简称为空类。空类中什么都没有吗?并不是的,任何一个类在我们不写的情况下,都会自动生成6个默认成员函数 ,构造函数,析构函数,拷贝函数,赋值重载函数,普通对象和const对象的取地址重载。这些函数如果创建类的人没有显式定义,编辑器将自己生成默认函数。

class Date {};

构造函数

  1. 概念

    ​ 对于一个类,我们可以定义一个方法,来对类的内容做出合适设置。但是这样频繁地调用方法是很麻烦的。能不能在这个类创建的时候就自动初始化呢?

    ​ 构造函数能做到这一点。构造函数是一个很特殊的成员函数,它的名字与类名相同,当创建一个类时,编辑器将自动调用该函数。保证类的每个数据成员都有一个合适的初始值。并且,该函数在类的生命的周期中只会调用一次

  2. 特性

    • 构造函数虽然有构造两字,但是构造函数并不是用来创建类的。它是在一个类被创建的时候,去初始化这个类

    • 构造函数的函数名与类目相同。

    • 构造函数没有返回值,注意这里的没有返回值就是什么不写,而不是写void。如下面代码就显式定义了一个构造函数。

    class Date
    {
    public:
    	void Print();
    	Date(int year = 2022, int month = 5, int day = 20)
    	{
    		_year = year;
    		_month = month;
    		_day = day;
    	}
    	
    private:
    	int _year;
    	int _month;
    	int _day;
    };
    
    • 当一个对象实例化的时候,编辑器会自动调用构造函数。

    • 构造函数可以重载。如下面代码就将构造函数进行了重载。

    class Date
    {
    public:
    	void Print();
    	Date(int year = 2022, int month = 5, int day = 20)
    	{
    		_year = year;
    		_month = month;
    		_day = day;
    	}
    	Date(int year,int month, int day)
    	{
    		_year = year;
    		_month = month;
    		_day = day;
    	}
    private:
    	int _year;
    	int _month;
    	int _day;
    };
    
    void Date::Print()
    {
    	cout << _year << "-" << _month << "-" << _day << endl;
    }
    
    int main()
    {
    	Date tmp;
    	tmp.Print();
    	Date x(2022, 5, 20);
    	x.Print();
    	return 0;
    }
    
    • 如果类中没有显式定义构造函数,编辑器会自动生成一个默认构造函数,如果有定义则不会生成。

    • 不管是我们显式定义的无参构造函数,还是全缺省构造函数,又或者是编辑器默认生成的构造函数,都称为默认构造函数。默认构造函数,在不初始化的创建,会自动调用默认构造,如:

    Date tmp;
    

    默认构造和普通构造是有些区别的,默认构造只允许存在一个

    • 对于编辑器生成的默认构造函数,其实是存在一些问题的。因为编辑器生成的默认构造函数并不会初始化内置类型成员(如int,char,float等),这些内置类型成员仍会为随机值。那这个默认构造在干嘛呢?

    虽然对于内置类型成员,生成的默认构造函数并不会初始化。但是对于自定义类型成员,生成的默认构造函数会去调用该自定义类型成员的默认构造函数

    也就是说,当我们的一个类,它的成员全是自定义类型时,而恰好这些成员的默认构造函数都有。那么我们就不需要去写这个类的默认构造函数,直接用编辑器生成的即可。

    析构函数

    1. 概念

      析构函数和构造函数刚好是相反的。构造函数用于初始化,析构函数则用于类的一些资源清理工作。注意析构函数并不是用来销毁对象的,销毁对象的工作是编辑器来完成的。当局部对象除了作用域时,编辑器进行销毁工作

      那么析构函数的资源清理是什么呢?其实就是有些类可能malloc了一些空间,当一个局部变量出了作用域时,这些空间可能没被释放。这就需要析构去将他们进行free。

    2. 特性

      • 析构函数的函数名为,~ + 类名。
      • 析构函数没有任何参数,也没有任何返回值。
      • 一个类只能有一个析构函数,如果没有显式定义,编辑器将自动生成默认的析构函数。
      • 当一个对象的生命周期结束后,编辑器将自动调用析构函数。
      • 和构造函数一样,当一个类中有自定义成员时,析构函数会调用这些自定义成员的析构函数。

    拷贝构造函数

    1. 概念

      在创建类时,我们能否,复制出一个一模一样的类呢?拷贝构造函数就能完成这件事。

      拷贝构造函数只有一个形参(不包括this),该形参是同类对象的引用,一般最好要加const修饰。当用已经存在的类型去创建一个新类型时,编辑器自动调用该函数。

    2. 特性

      • 拷贝构造是构造的一种重载。
      • 拷贝构造只有一个参数,且必须是同类对象的引用。如果是传值参数,将会发生无限循环。因为形参是实参的一份拷贝。当把这个形参传入时,又需要拷贝构造。就这样无限循环。而且最好加const修饰,防止权限的放大。
      • 如果没有显式定义拷贝构造函数,编辑器将生成默认的拷贝构造函数。默认的拷贝构造函数对于内存的中的数据进行按字节完成拷贝。这种拷贝叫做浅拷贝,也叫值拷贝。但是这种拷贝是有问题的,例如当类中有指针变量时,浅拷贝只会把两个指针变成相同的值,而忽略了实际意义。如当这个指针指向的是一个栈时,浅拷贝只是让两个指针指向同一个栈,而没有去创建一个新的栈。

    运算符重载

    1. 概念

      C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数。该函数名为关键字operator加需要重载的运算符符号。

      注意:

      • 不可以通过operator来引入新的操作符。
      • 重载操作符必须要一个类类型或者枚举类型的操作数。
      • 用于内置类型的操作符,其含义不能改变,如:int+,不能改变其+的含义。
      • 运算符重载,都默认有一个this形参,且限定为第一个形参。
      • *. ** , :: , sizeof , **?: ** , . 注意这五个运算符时不可以重载的。
    2. 特性

      • 当一个类要实现 += 和 + 时,优先实现 += ,然后用 += 实现 + ,会提高效率。
      • 前置++ 和 后置++ 是不相同的,一是前置++除了this外没有参数,后置++除了this外还有一个参数,只是这个参数可以只写int,而不写参数名。二是前置++,返回的是++后的 *this,后置++返回的是,修改前的 *this(创建临时变量,用来返回)。

    const成员函数

    1. 概念

      将const修饰的类成员函数称之为const成员函数。const修饰类成员函数,实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改。

    2. 特性

      class Date
      {
      public:
      	void Print() const
      	{
      		cout << _year << "-" << _month << "-" << _day << endl;
      	}
      private:
      	int _year;
      	int _month;
      	int _day;
      };
      

      当加上const修饰后,*this将会被修饰,不能被改变。

    取地址及const取地址操作符重载

    这两个默认成员函数一般不需要重现定义,编辑器会默认生成。

    class Date
    {
    public:
    	Date* operator&()
    	{
    		return this ;
    	}
    	const Date* operator&()const
    	{
    		return this ;
    	}
    private:
    	int _year ; // 年
    	int _month ; // 月
    	int _day ; // 日
    };
    

rn this ;

  }
  const Date* operator&()const
  {
  	return this ;
  }

private:
int _year ; // 年
int _month ; // 月
int _day ; // 日
};

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

roseisbule

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值