C++中类的6个默认成员函数

这里写图片描述
1.构造函数
构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时,由编译器自动调用,在对象的生命周期内只且值调用一次,以保证每个数据成员都有一个合适的初始值。
【构造函数特性】
1、函数名与类名相同。
2、没有返回值。
3、有初始化列表(可以不用)。
4、新对象被创建,由编译器自动调用,且在对象的生命期内仅调用一次。
5、构造函数可以重载,实参决定了调用那个构造函数。
6、如果没有显示定义时,编译器会提供一个默认的构造函数。
如果一个类中没有定义任何的构造函数,那么编译器只有在以下三种情况,才会提供默认的构造函数:
1、如果类有虚拟成员函数或者虚拟继承父类(即有虚拟基类)时;
2、如果类的基类有构造函数(可以是用户定义的构造函数,或编译器提供的默认构造函数);
3、在类中的所有非静态的对象数据成员,它们对应的类中有构造函数(可以是用户定义的构造函数,或编译器提供的默认构造函数)
7、无参构造函数和带有缺省值得构造函数都认为是缺省构造函数,并且缺省构造函数只能有一个。
因为在调用是如果出现Date( ),编译器并不知道该调用哪一个构造函数;

      Date( int year = 1990, int month = 1, int day = 1)
      {
      }
      //
      Date( )
      {
      }

8、构造函数不能用const来修饰,为什么呢?

【初始化列表】
初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个数据
成员后面跟一个放在园括号中的初始化式。

        Date(int year = 1990, int month = 1, int day = 1)
                   :_year(year)
                   , _month( month)
                   , _day( day)
          {
          }

常量,变量的引用,和没有缺省初始化的类必须在初始化列表中初始化;
【初始化顺序】
1、每个成员在初始化列表中只能出现一次。(为什么?)
2、初始化列表仅用于初始化数据成员,并不指定这些数据成员的初始化顺序,
数据成员在类中定义顺序就是在参数列表中的初始化顺序。
3、尽量避免使用成员初始化成员,成员的初始化顺序最好和成员的定义顺序保持一致。
【默认构造函数】
类如果没有显式定义构造函数时,编译器会合成一个默认的构造函数,该构造函数中什么工作都不做。只要显式定义了,即使该构造函数什么也不做,编译器也不会为该类合成默认的构造函数。编译器生成的默认构造函数使用与变量初始化相同的规则来初始化成员,具有类类型的成员通过运行各自的默认构造函数来进行初始化。内置和符合类型的成员如指针、数组,只对定义在全局作用域中的对象初始化,当对象定义在局部作用域时,内置和符合类型的成员不进行初始化。在某些情况下,默认构造函数是由编译器隐式使用的。

构造函数作用:
1、构建对象
2、初始化对象
3、类型转换
【explcit】
用explicit修饰构造函数,抑制由构造函数定义的隐式转换,erplicit关键字类内部的构建声明上,在类的定义体外部的定义上不再重复。

例:Date类的构造函数:

class Date
{
public:
          Date( int year = 1990, int month = 1, int day = 1)//带默认值
                   :_year( year)//初始化列表
                   , _month( month)
                   , _day( day)
          {

          }

private:
           int _year;
           int _month;
           int _day;
}

2.拷贝构造函数
只有单个形参,而且该形参是对本类类型对象的引用(常用const修饰),这样的构造函数称为拷贝构造函数。拷贝构造函数是特殊的构造函数,创建对象时使用已存在的同类对象来进行初始化,由编译器自动调用。
Date(const Date & d)
{
_year = d ._year;
_month = d ._month;
_day = d ._day;
}
【特征】
1、它是构造函数的重载。
2、它的参数必须使用同类型对象的引用传递。(思考为什么?)

3、如果没有显式定义,系统会自动合成一个默认的拷贝构造函数。默认的拷贝构造函数会依次拷贝类的数据成员完成初始化。

【使用场景】
1、对象实例化对象
Date d1(1990, 1, 1);
Date d2(d1);

2、传值方式作为函数的参数
void FunTest(const Date date)
{}

3、传值方式作为函数返回值
Date FunTest()
{
Date date;
return date;
}
3.析构函数
析构函数:与构造函数功能相反,在对象被销毁时,由编译器自动调用,完成类的一些资源清理和汕尾工作;
【特性】
a、析构函数在类名(即构造函数名)加上字符~。
b、析构函数无参数无返回值。
c、一个类有且只有一个析构函数。若未显示定义,系统会自动生成缺省的析构函数。
d、对象生命周期结束时,C++编译系统系统自动调用析构函数。
e、注意析构函数体内并不是删除对象,而是做一些清理工作。
f、 认识到析构函数体本身并不直接销毁成员是非常重要的。成员是在析构函数体之后隐含的析构阶段中被销毁的。
【什么时候会调用析构函数】
无论何时,一个对象被销毁,就会自动调用其析构函数:
a.变量离开其作用域是被销毁;
b.当一个对象的销毁时,其成员被销毁;
c.容器(无论是标准库容器还是数组)被销毁时,其元素被销毁;
d.对于动态分配的对象,当指向它的指针用delete运算符被销毁;
e.对于临时对象,当创建它的完整表达式结束时被销毁。
【 warning】
当指向一个对象的引用或指针离开作用域时,析构函数不会执行。
4.赋值操作符重载;
5.取地址操作符重载;
6.const修饰的取地址操作符重载;
【操作符重载】

重载操作符是具有特殊函数名的函数,关键字operator后面接需要定义的操作符符号。
操作符重载也是一个函数,具有返回值和形参表。它的形参数目与操作符的操作数目相同,
函数调用操作符可以接受任意数目的操作数。
返回类型 operate 操作符(参数列表);

注意:
1、不能通过连接其他符号来创建新的操作符:比如operator@;
void operator @(){}

2、重载操作符必须有一个类类型或者枚举类型的操作数
int operator +(const int _iNum1 , const int _iNum2 ) // 报错
{
return ( _iNum1 + _iNum2);
}

typedef enum TEST {one ,two ,three };
int operator+(const int _iNum1 , const TEST _test )
{
return _iNum1;
}

3、用于内置类型的操作符,其含义不能改变,例如:内置的整型+,不能改变其含义

5、不在具备短求职特性
重载操作符不能保证操作符的求职顺序,在重载&&和||中,对每个操作数
都要进行求值,而且对操作数的求职顺序不能做规定,因此:重载&&、
||和逗号操作符不是好的做法。

6、作为类成员的重载函数,其形参看起来比操作数数目少1
成员函数的操作符有一个默认的形参this,限定为第一个形参。
CTest operator+(const CTest test1, const CTest test2)const // 报错
{
return test1;
}

CTest operator+(const CTest test1)const
{
return test1;
}

7、一般将算术操作符定义为非成员函数,将赋值运算符定义成员函数
8、操作符定义为非类的成员函数时,一般将其定义为类的友元函数
9、== 和 != 操作符一般要成对重载
10、下标操作符[]:一个非const成员并返回引用,一个是const成员并返回引用
11、解引用操作符*和->操作符,不显示任何参数
13、自增自减操作符
前置式++/–必须返回被增量或者减量的引用
后缀式操作符必须返回旧值,并且应该是值返回而不是引用返回
14、输入操作符>>和输出操作符<<必须定义为类的友元函数
【建议】
使用重载操作符,可以令程序更自然、更直观,而滥用操作符重载会使得类难以理解,在实践中很少发生明显的操作符重载滥用。但有些程序员会定义operator+来执行减法操作,当一个重载操作符不明确时,给操作符取一个名字更好,对于很少用的操作,使用命名函数通常比用操作符好,如果不是普通操作,没有必要为简洁而用操作符。

赋值操作符重载;(以Date类为例)
Date& operator=(const Date& d)//定义为类的成员函数
{
_year = d._year;
_month = d._month;
_day = d._day;
return *this ;
}
取地址操作符重载和const修饰的取地址操作符重载; ;
class CTest
{
public:
CTest* operator&()
{
return this ;
}

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

};

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值