美文网首页
C++之类的构造函数、析构函数

C++之类的构造函数、析构函数

作者: EamonXia | 来源:发表于2019-03-07 20:10 被阅读0次

一、认识构造函数

  当创建一个类的对象时,主要是通过一个或者几个特殊的成员函数来控制对象的初始化,这种函数就是构造函数。它的任务就是用来初始化类的成员的,所以当创建类对象时候就会调用构造函数。
  构造函数的几个特点:

    1. 函数名和类名必须一样,且没有返回值。
    1. 当没有显式的定义类的构造函数时,系统会自己生成默认的构造函数。
    1. 构造函数可以重载。
class Date
{
public:
    Date()
    { }
    Date(int day)
    {
        _year = 1949;
        _month = 10;
        _day = day;
    }
    void print()
    {
        cout << _year << "-" << _month << "-" << _day << endl;
    }

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

  上面的代码中,定义了一个简单的Date类类型,可以看到有显式的给出了构造函数,第一个是没有参数列表且函数体不做任何操作的,还有一个是仅有一个整形参数day的,就是当我传入一个整形的day参数,则在函数内部就把它的_year和_month初始化为1949跟10,而_day初始化为传入的实参值。这样的两个构造函数就构成了重载,因为能够重载,所以在写构造函数的时候只能有一个参数列表为空的构造函数(\color{red}{也叫缺省的构造函数}
  当不传参数的定义一个Date类型对象,会调用显式定义的缺省的构造函数,在没有初始化列表的情况下采取类内初始化或默认初始化,上面的程序中,如果不传入参数,那么构建的对象的_year成员初始化为1990,另外两个值随机。
\color{red}{牢记:}
  我们在没有显式的定义构造函数时候,系统会自动生成一个默认构造函数。当我们定义了一些其他的构造函数时,这个类就将没有默认构造函数。所以当我们显式的定义了其他的构造函数,最好把默认构造函数也显式的定义一遍。\color{red}{这样是有巨大好处的,就是系统生成的默认构造函数有可能执行错误的操作,或者无法完成类成员的初始化}
\color{red}{(e.g.有一成员是类类型的对象且它没有缺省的构造函数)}
  当我们定义的默认构函数,并不需要做什么事情的时候,只是因为需要满足上面所提的情况才显式的定义它时,那么此时的默认构造函数等同于系统生成的默认构造函数,那么我们可以这么写:
          Date() = default;
  因为在新标准中,如果需要系统默认的行为,就可以通过在参数列表后加上=default来使编译器生成系统默认的构造函数。

二、初始化列表

  如下面代码所示,在冒号:跟花括号{}之间的代码成为构造函数的初始值列表,它的作用是给创建的对象的某些成员变量赋初值。这种是在构建对象的时候初始化,是在对象创建成功之前完成的,和在函数体内赋值是不一样的,函数体内赋值是你的对象成员都已经创建好之后,再对成员进行赋值。

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

  可以看到,这种初始化并不是必须的,但是在以下几种情况时是必须的:

  • 1.成员是const类型。
    1. 成员是引用类型。
    1. 有一个成员是类类型的对象(且它没有缺省的构造函数)。
class Time
{
public:
    Time( ) 
    {
        
    }

private:
    int _hour;
};
class Date
{
public:
    Date(int year=1990,int month=1,int day=1)
        :_year(year), _month(month), _day(day), t(10)
    { }
    void print()
    {
        cout << _year << "-" << _month << "-" << _day << endl;
    }
private:
    int _year=1990;
    int _month;
    int _day;
    Time t;
};

解释:

  1.对于const和引用类型,必须要进行初始化,所以他们必须在初始化列表中进行初始化。
  2.当类类型成员有缺省的构造函数时,在创建对象的时候体统会默认调用,因为不用传参。当你的构造函数不是缺省的,如果不在初始化列表中进行调用构造函数,系统就无法知道怎么调用t的构造函数,那么就无法创建t了。
  如上代码中,需要在参数列表中调用t的构造函数才不会出错。

成员初始化顺序:

  在上面的初始列表中,每个成员只能出现一次,因为一个变量多次初始化是无意义的。
  还有重要的一点,初始化列表的顺序并不限定初始化的执行顺序。成员的初始化顺序是与类中定义的顺序保持一致。可以看看下面的初始化列表:

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

  在这里的意思是想要用1来初始化_month,再用_month初始化_year。但其实是_year被先初始化,而此时你的_month并没有初始化,所以,最后的结果是_year是一个随机值。
  所以,最好让构造函数初始值的顺序与成员声明的顺序保持一致。

相关文章

  • 简介python中的析构函数与构造函数

    python的构造和析构函数为固定的名字。 构造函数 析构函数 不像c++中那样构造函数和析构函数是类名字。并且在...

  • c++构造函数,析构函数,调用顺序

    最近,在看c++,聊一个简单的话题吧。构造函数,析构函数,及调用顺序。 构造函数, 构造函数,析构函数,如上代码所...

  • [C++之旅] 13 析构函数

    [C++之旅] 13 析构函数 析构函数与构造函数相反,构造函数在实例化一个对象时调用,而析构函数在销毁一个对象时...

  • c++学习笔记2(GeekBand)

    拷贝构造、拷贝赋值和析构 c++中有Big Three三个特殊的函数,他们就是拷贝构造函数,拷贝赋值函数和析构函数...

  • 2002.C++BASE-构造函数、析构函数

    转:C++继承中构造函数、析构函数调用顺序及虚析构函数 1.构造函数 大家都知道构造函数里就可以调用成员变量,而继...

  • Python:重载构造方法

    对于使用过C++的人来说,构造函数与析构函数不会陌生。构造函数在对象创建时被调用,析构函数在对象被销毁时被调用。而...

  • g2o CurveFittingEdge

    构造函数与析构函数:C++大括号{}有作用于,在作用域范围结束时,调用结构体的析构函数,构造函数是与类同名人那个函...

  • 构造函数

    构造函数 构造函数的数组的应用 类中包含类,并且给类传参 析构函数(逆构造函数):每个构造函数都析构函数,谁最先构...

  • windows逆向3

    VC 程序内存和编译的一些特征C++ 构造函数C++ 成员函数C++ 析构函数C++ 全局对象的构造C++ 全局对...

  • c++面向对象-构造、析构、初始化列表

    构造函数 构造函数是指创建对象的时候,会调用的函数。C++构造函数可以重载,指针或者对象均可调用构造函数。 析构函...

网友评论

      本文标题:C++之类的构造函数、析构函数

      本文链接:https://www.haomeiwen.com/subject/olphpqtx.html