21xrx.com
2024-12-28 13:36:53 Saturday
登录
文章检索 我的文章 写文章
C++初始化列表顺序详解
2023-07-07 05:04:30 深夜i     --     --
C++ 初始化列表 顺序 详解

在C++中,对象的初始化是非常重要的一个部分,而对象初始化列表就是C++中非常重要的一个概念。C++中的所有类都有构造函数,当我们创建一个对象或者实例时,构造函数会被调用,这时我们可以通过初始化列表来初始化对象的各个属性。

对象初始化列表提供了一种非常有效的方式来初始化类成员,不仅可以初始化类成员变量,还可以对基类进行初始化、调用父类的构造函数以及初始化常量成员。但是,在使用初始化列表时,要注意初始化的顺序,因为这与避免一些未定义行为有关。

1. 对象初始化列表顺序规则

C++规定,在对象初始化列表中,成员初始化的顺序与成员的声明顺序一致。这意味着,如果我们先声明了成员变量A,再在后面声明了成员变量B,那么,在对象初始化列表中,A将先于B被初始化。

例如:


class Test

{

public:

  Test(int a, int b) : m_a(a), m_b(b)

   m_b=" << m_b << endl;

  

  

private:

  int m_a;

  int m_b;

};

在这个例子中,成员变量m_a声明在m_b前面,因此,在对象初始化列表中,m_a将先于m_b被初始化。

2. 合成对象初始化顺序规则

当一个类的成员变量中包含另一个类的对象时,初始化顺序可能会更加复杂。在这种情况下,C++ 规定的初始化顺序如下:

(1)基类的初始化顺序按照它们在继承列表中出现的顺序进行初始化。

(2)成员的初始化顺序是按照它们在类中声明的顺序进行初始化。

例如:


class Base

{

public:

  Base(int val) : m_val(val)

  {

    cout << "Base::Base()" << endl;

  }

  void Func()

  {

    cout << "Base::Func(), m_val = " << m_val << endl;

  }

private:

  int m_val;

};

class Derived

{

public:

  Derived() : m_a(10), m_b(20), m_base(30)

  {

    cout << "Derived::Derived()" << endl;

  }

  void Func()

  {

    cout << "Derived::Func(), m_a = " << m_a << ", m_b = " << m_b << endl;

    m_base.Func();

  }

private:

  int m_a;

  Base m_base;

  int m_b;

};

在这个例子中,Derived 类中的成员变量包括一个整型变量 m_a,一个 Base 类对象 m_base 和一个整型变量 m_b 。在对象初始化列表中,m_a、m_b和m_base的初始化顺序是确定的,分别对应上述代码中的 10、20 和 30 。由于m_base是一个Base类类型,所以它将在m_a和m_b之后被初始化,这与m_base在Derived类中的声明位置无关。

总之,在使用C++中初始化列表时,要遵循一定的顺序规则,以避免一些未定义行为的出现。同时,合理使用对象初始化列表可以提高代码的效率和可读性。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复