必须使用构造函数初始化列表的几种情况

发布时间 2023-10-26 11:13:03作者: Hombre

C++中的普通成员变量可以在构造函数列表里初始化,也可以在构造函数中通过赋值初始化,但以下几种成员变量只能通过初始化列表进行初始化:

1.非静态常量(non-static const)

#include<iostream> 
using namespace std; 
  
class Test { 
    const int t; //C++11之后可以直接在定义后初始化: const int t = 0;
public: 
    Test(int t):t(t) {}  //Initializer list must be used 
    int getT() { return t; } 
}; 
  
int main() { 
    Test t1(10); 
    cout<<t1.getT(); 
    return 0; 
} 
  
/* OUTPUT: 
   10  
*/

2.引用 (reference)

#include<iostream> 
using namespace std; 
  
class Test { 
    int &t; 
public: 
    Test(int &t):t(t) {}  //Initializer list must be used 
    int getT() { return t; } 
}; 
  
int main() { 
    int x = 20; 
    Test t1(x); 
    cout<<t1.getT()<<endl; 
    x = 30; 
    cout<<t1.getT()<<endl; 
    return 0; 
} 
/* OUTPUT: 
    20 
    30 
 */

3.没有默认构造函数的对象 (objects which do not have default constructor)

#include <iostream> 
using namespace std; 

class A { 
    int i; 
public: 
    A(int ); 
}; 

A::A(int arg) { 
    i = arg; 
    cout << "A's Constructor called: Value of i: " << i << endl; 
} 

// Class B contains object of A 
class B { 
    A a; 
public: 
    B(int ); 
}; 

B::B(int x):a(x) { //Initializer list must be used 
    cout << "B's Constructor called"; 
} 

int main() { 
    B obj(10); 
    return 0; 
} 
/* OUTPUT: 
    A's Constructor called: Value of i: 10 
    B's Constructor called 
*/

4.派生类初始化基类对象 (base class members)

#include <iostream> 
using namespace std; 

class A { 
    int i; 
public: 
    A(int ); 
}; 

A::A(int arg) { 
    i = arg; 
    cout << "A's Constructor called: Value of i: " << i << endl; 
} 

// Class B is derived from A 
class B: A { 
public: 
    B(int ); 
}; 

B::B(int x):A(x) { //Initializer list must be used 
    cout << "B's Constructor called"; 
} 

int main() { 
    B obj(10); 
    return 0; 
} 

注:1.当构造函数参数和成员变量相同时,必须通过构造函数列表初始化或者通过this指针赋值。

       2.构造函数初始化列表初始化顺序与成员变量声明顺序相同

       2.使用构造函数初始化列表拥有更好的性能,见以下例子

#include <iostream>
using namespace std;

class Type
{
public:
    Type() { 
        cout << "default constructor called." << endl; 
    }

    Type(const Type &t) { 
        cout << "copy constructor called." << endl; 
    }

    Type& operator= (const Type &t) {
        if (this == &t)
            return *this;
        cout << "assignment operator called." << endl;
        return *this;
    }
};

class TestA
{
    Type a;
public:
    TestA(const Type &t):a(t) { //a调用一次拷贝构造函数
    }
};

class TestB
{
    Type b;
public:
    TestB(const Type &t) {
        b = t;  //b先调用默认构造函数,再调用赋值操作符
    }
};

int main()
{
    Type t;
    cout << "-----Test A--------" << endl;
    TestA a(t);

    cout << "-----Test B--------" << endl;
    TestB b(t);

    return 0;
}

 

 

参考链接:https://www.geeksforgeeks.org/when-do-we-use-initializer-list-in-c/