构造函数和初始化表

1.无参构造-默认构造函数

    无参并非严格的没有参数的构造函数,而是不需要提供实际参数的构造函数,比如存在有默认参数

    Integer::Integer(int a = 10);//也算是默认构造函数,可以无参调用。

    Integer* p1 = new Integer();
    Integer* p2 = new Integer;

    Integer i();

    Integer i;//建议方式

    关于对象的无参构造在使用时可以不用()的不带();

    第三种构造方式下,如果该Integer不存在无参构造函数,会直接将其当做函数声明从而可能引发编译器报错。

2.单参构造-类型转换构造

    单参构造函数,向编译器提供一种隐式的类型转换。

    explicit Integer::Integer(int data);

  •  比如函数返回值为  Integer 类型,而实际返回的为int类型,则会隐式调用类型转换构造函数将int类型构造为Integer类型。
  • 比如形参为Integer类型,而实际调用时使用的是 int类型,编译器同样会隐式调用类型转换构造函数将int类型构造为Integer类型。
  • 如果不让编译器隐式类型转换,则可以在该类型转换构造函数前添加explicit修饰,如此,如果发生隐式类型转换则编译器报错。如果想要转换则必须使用static_cast进行显示转换。

3.拷贝构造 

    拷贝构造函数必须传递引用型参数。

        Integer::Integer(Integer const& that);     

  •         如果未定义构造函数,则系统提供缺省构造函数和缺省拷贝构造;
  •         如果定义了非拷贝构造,则系统也提供缺省拷贝构造;
  •         如果定义了拷贝构造,则系统不再提供构造函数。

        即如果一个类如果只有一个构造函数,则一定是拷贝构造函数。

    另外:  如果传递非引用参数,则会通过拷贝构造形成一个匿名的Integer副本,导致无限调用自身,陷入死循环。

初始化表:

    初始化表不是执行过程,而是指导成员变量的定义和初始化,初始化过程是按照类中成员变量的声明顺序,而非初始化表中的顺讯。

初始化表在以下情况下必要:

   类的类类型成员变量,要么在初始化表中显式的初始化,要么通过相应类型的缺省构造函数初始化。

但是,如果类成员没有缺省构造函数,则必须使用初始化表来初始化。

class A {
public:
    A (int data) : m_data (data) {}
    int m_data;
};
class B {
public:
    B (int data) : m_a (data) {}
    A m_a; //B无法缺省构造,因为A无法缺省构造。
};

    另外类的常量型和引用型成员变量,必须在初始化表中显示初始化,不能在构造函数体中初始化。

    本质上,初始化表中的声明属于类成员的定义并初始化,而构造函数体中属于赋值。

    故而:常量型和引用型成员因为必须在定义时就初始化,所以必须在初始化表中进行显式初始化。


   构造函数的执行顺序:

        用A类定义一个对象或指向A对象的指针,首先是分配sizeof(A)的内存,然后调用A的构造函数,进行初始化A的对象。

        也是new包含malloc和调用A:A(...)构造函数。

    父子类的构造析构顺序:

         构造时先调用基类的构造函数,再调用派生类的构造函数

         析构时先调用派生类的析构函数,再调用基类的析构函数。   

 

    

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值