> 文章列表 > 默认成员函数之构造函数,构造函数的特点,创建,调用与对象创建的一语双关,默认构造函数等

默认成员函数之构造函数,构造函数的特点,创建,调用与对象创建的一语双关,默认构造函数等

默认成员函数之构造函数,构造函数的特点,创建,调用与对象创建的一语双关,默认构造函数等

内置类型与自定义类型

  1. C++当中的类型的话分为两类:一种就是内置类型/基本类型,就是c语言自带的那些类型基本类型,如int, char, double, 指针(任何类型的指针,因为指针就是地址嘛)等等;
  2. 还有就是自定义类型,用struct, class, union枚举联合等等自定义的类型
  3. 然后对于这个编译器自己生成的构造函数,对于内置类型不做处理;对于自定义类型,会去调用它的默认构造

默认成员函数

  1. 如果一个类中什么成员都没有,简称为空类。空类中真的什么都没有吗?并不是,任何类在什么都不写时,编译器会自动生成以下6个默认成员函数
  2. 默认成员函数:用户没有显式实现,编译器会生成的成员函数称为默认成员函数
    在这里插入图片描述

构造函数(初始化类的实例化对象)

  1. 千万不能把构造函数与析构函数当成普通的函数来对待,他们是特殊的成员函数,并不是普通的函数。
  2. 构造函数的作用就是初始化该类的实例化对象
  3. 构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,以保证每个数据成员都有 一个合适的初始值,并且在对象整个生命周期内只调用一次。
  4. ***函数名定死,与类名相同;无返回值,也不需要写void什么的,直接不写,因为是祖师爷的亲儿子;当一个对象被实例化出来之后,编译器自动调用对应的构造函数。***也就是说当一个类的实例化对象一旦被创建出来,直接编译器自动调用初始化函数直接被初始化了。
  5. 有时候我们可能有很多种初始化的方式,就比如说拿数据结构栈来举个例子,初始化的时候,我可能有一串原始数据需要放进去,也有可能什么都不放,可能有多种初始化的方式。这就导致构造函数可以重载。
  6. 但我们自己没有去写显示的构造函数的时候,编译器它会自动的生成一个构造函数。因为构造函数它是自动调用,如果你自己写了构造函数,他就自动调用你的,如果你不写构造函数,他自己也会写一个构造函数,然后去调用。
  7. 然后你去观察一下编译器自己生成的一个构造函数,你会发现它好像什么屁事儿也没干。实际上这个编译器生成的构造函数还是在给你初始化的,只是没有给你初始化成零而已。
  8. 这个编译器自己生成的构造函数,对于内置类型不做处理;对于自定义类型,会去调用它的默认构造默认构造函数对于那些自定义类型的成员变量,是绝对会给你初始化处理的,但是对于内置类型的成员变量不一定会处理,最终还是要取决于编译器,但一般来说是不处理。
  9. 在一般情况下,类有内置类型成员,就需要自己写构造函数,因为如果说你自己不写,然后仅靠编译器自动生成的构造函数,它可能不会给你的内置类型成员初始化。但如果说这个类当中全部都是自定义类型成员,那可以考虑让编译器自己生成构造函数。
  10. 构造函数是支持函数重载的,这边就又需要回归到函数承载的那个问题。当函数重载当中有缺省参数参与进来的时候,有时候两个函数确实是构成了函数重载,但是调用(特别是无参调用)的时候还是会引起歧义。
  11. 在类的构造函数里面可以支持全缺省,半缺省。
  12. 一旦显式定义任何构造函数,编译器将不再生成,如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义编译器将不再生成

构造函数的特点

  1. 名字就是类名,没有且不写返回值
  2. 实例化对象创建的下一秒构造函数就会自动被调用
  3. 支持函数重载
  4. 你写了就用你的,没写就用我编译器自己的,但我只负责自定义类型的初始化
  5. 在对象整个生命周期内只调用一次
    在这里插入图片描述
    在这里插入图片描述

构造函数的创建(无参,有参,支持函数重载)

  1. 无参构造函数
class A
{
public:A(){a = 10;b = 20;c = 30;d = 'S';}void Print(){cout << a << " " << b << " " << c << " " << d << endl;}
private:int a;int b;int c;char d;
};
  1. 带参构造函数
class A
{
public:A(int pa, int pb, int pc, int pd){a = pa;b = pb;c = pc;d = pd;}void Print(){cout << a << " " << b << " " << c << " " << d << endl;}
private:int a;int b;int c;char d;
};
  1. 构造函数是可以进行函数重载的,也就是说函数名可以相同,只要参数那边不同就可以。
class A
{
public:A(int pa, int pb, int pc, int pd){a = pa;b = pb;c = pc;d = pd;}A(){a = 10;b = 20;c = 30;d = 'S';}void Print(){cout << a << " " << b << " " << c << " " << d << endl;}
private:int a;int b;int c;char d;
};

构造函数的调用与实例化对象的创建(代码一语双关)

  1. 构造函数调用与普通函数也不一样
  2. 首先构造函数是可以进行函数重载的,也就是说函数名可以相同,只要参数那边不同就可以。
  3. 构造函数函数名 类的实例化对象(有参数就传入参数,没有参数直接分号)
  4. 正是因为类的构造函数它特别特别的怪,它的名字就是与类名一模一样,所以说对于创建类的实例化对象的代码,一方面可以把他看成创建了一个类的实例化对象;另一方面也可以把它看成是一次构造函数的调用(构造函数的调用与普通函数是不一样的,不要以普通函数的视角去看待)
    在这里插入图片描述
  5. 一语双关。
    在这里插入图片描述
    在这里插入图片描述

默认构造函数

  1. 无参的构造函数全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。
  2. 注意:无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数,都可以认为是默认构造函数。
  3. 我们自己写的不传参就能够调用的构造函数(无参构造函数,全缺省构造函数),我们没写编译器默认生成的构造函数都是默认构造函数。
    在这里插入图片描述

C++11对于创建类的新补丁

  1. C++11的标准发布的时候打了个补丁,但打补丁并不是把之前的语法标准给他改了,可不敢这样。
  2. 在成员声明的时候可以给缺省值,这个就主要针对的是内置类型。
  3. 这个并不是函数里面的那个缺省参数,这边的意思是在类的声明当中就可以直接对那些内置类型的成员变量给一个缺省值。
  4. 但这个并不是初始化,因为这边只是声明,也没有开空间。这边的这个值缺省值,专门给编译器默认生成的构造函数用的。
    在这里插入图片描述
    在这里插入图片描述