C++ 初始化列表与赋值
Posted
技术标签:
【中文标题】C++ 初始化列表与赋值【英文标题】:C++ initialization list vs assigning values 【发布时间】:2020-05-11 03:17:19 【问题描述】:在 C++ 中,初始化列表和在构造函数中赋值而不是每个方法的外观有什么区别? 我的意思是使用一个而不是另一个的优点是什么,为什么在幻灯片(下)的给定示例中仅适用于初始化? (我没找到,希望能加点资源)
Click here to view slide: uploaded on imgur
【问题讨论】:
【参考方案1】:在构造函数中使用初始化列表是一步过程,即它在声明对象的那一刻初始化对象。它调用复制构造函数。
而使用分配是两步过程,即定义对象然后分配它。定义对象调用默认构造函数,然后赋值调用赋值运算符。因此,昂贵的操作。
在C++中,类的常量或引用数据成员变量只能在初始化列表中初始化,不能在构造函数体中使用赋值。
常量和引用数据成员变量都具有必须在声明时初始化的属性。因此,只有在构造函数中使用初始化列表,因为初始化列表在声明时初始化类成员变量,而如果构造函数主体在声明后初始化数据成员,则赋值。
在某些情况下,构造函数内的数据成员初始化不起作用,必须使用初始化列表。以下是此类情况。
-
用于初始化非静态 const 数据成员。
#include<iostream> using namespace std; class Test const int t; 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;
-
用于引用成员的初始化。
#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;
-
用于初始化没有默认构造函数的成员对象。 (在您的情况下 Array digits 没有默认构造函数)
#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;
-
用于基类成员的初始化。
当构造函数的参数名称与数据成员相同时。
出于性能原因。
【讨论】:
【参考方案2】:如果不使用初始化列表,则在到达构造函数主体之前,将默认构造类的数据成员:
class Foo
private:
int bar;
public:
Foo(int _bar)//bar is default constructed here
bar = _bar; //bar is assigned a new value here
;
这对于基本类型(如int
)来说不是什么大问题,因为默认构造函数并不昂贵。但是,如果数据成员没有默认构造函数,或者默认构造后赋值比直接构造更昂贵,则可能会成为问题:
//Bar does not have a default constructor, only a copy constructor
class Bar
public:
Bar() = delete; //no default constructor
Bar(const Bar& bar); //copy constructor only
;
class Foo
private:
Bar bar;
public:
Foo(const Bar& _bar)
//this will not compile, bar does not have a default constructor
// or a copy assignment operator
bar = _bar;
Foo(const Bar& _bar) : bar(_bar)//this will compile, copy constructor for bar called
;
一般来说,使用初始化列表可以获得更高效的代码。
【讨论】:
嗨,为什么“Bar 没有默认构造函数”我在读到,当我们不编写构造函数时,编译器会为我们提供默认构造函数,除非我们声明其他任何构造函数......另外,可以举个例子详细说明一下:“但是,如果数据成员没有默认构造函数,或者默认构造后赋值比直接构造更昂贵,则可能会成为问题:” @clark_smith1 如果您查看第二个代码 sn-p,我已经使用Bar()=delete
显式删除了 Bars 默认构造函数。这可以防止编译器构造一个。因此,Bar 没有任何构造函数。以上是关于C++ 初始化列表与赋值的主要内容,如果未能解决你的问题,请参考以下文章