我一直在阅读"C++入门".对于对象的初始化,C++支持两种形式的初始化:直接和复制.但本书并未参考初始化参考.在书中我从未见过直接初始化(如果存在)引用.一切都像副本一样:
int i;
int &j = i;//but not int &j(i);which also works in my experiment
Run Code Online (Sandbox Code Playgroud)
我想知道它是在下面进行的初始化参考.对于以下代码:
string null_book = "9-999-99999-9";
Run Code Online (Sandbox Code Playgroud)
初始化进程首先创建一个临时string对象TMP(例如),将直接与AC风格字符串参数初始化,然后初始化变量null_book与拷贝构造函数.这对我来说很有意义.对于这一个:
int &j = i;
Run Code Online (Sandbox Code Playgroud)
ref ref会以同样的方式初始化吗?那将是一个临时引用它&t(例如)由i初始化然后用t初始化j?这没有意义??? 为什么书从不使用直接初始化作为参考?感谢您的关注!
直接初始化和复制初始化之间的主要区别在标准的第8.5节第17节中有所介绍.通常,不同之处在于,对于复制初始化中的类类型,不考虑显式构造函数(仅考虑转换构造函数),并且可能省略了复制; 在直接初始化中,考虑显式构造函数,并直接构造目标.从标准第8.5节开始:
14 - 初始化的形式(使用括号或
=)通常是无关紧要的,但是当初始化器或正在初始化的实体具有类类型时,这很重要[...]
对于非类类型(包括引用),直接初始化和复制初始化具有类似的语义; 对于引用,在两种情况下都会发生引用绑定,如8.5.3引用[dcl.init.ref]中所述.直接初始化和复制初始化的参考的仅具有其中一个转换功能是参与(不同的语义通过用于直接参照结合[over.match.ref]转换功能13.3.1.6初始化); 同样,允许直接初始化调用显式转换函数,而不是复制初始化.
所以,在
int &j = i;
Run Code Online (Sandbox Code Playgroud)
8.5.3p5适用,引用j直接绑定到左值i.没有临时调用.
就复杂性而言,引用更接近基本(原始)类型而不是类类型.初始化是在没有临时构建的情况下初始化的(8.5p17,最后一个子弹),一般参考也是如此.这可能就是为什么本书只使用=表格来初始化参考文献; 与原语一样,通常没有区别,写作int i = x;通常比清晰int i(x);.
术语复制初始化和直接初始化是C++语法的一部分。它们不会立即告诉您发生了什么样的代码生成。任何语法结构的含义都是由标准描述的,并且初始化的上下文有许多不同的特定结果,具体取决于正在初始化的事物的类型。
特别是,对于原始类型、指针类型和引用类型,直接初始化和复制初始化(语法结构!)具有完全相同的效果。也就是说,基本类型和指针类型使用初始值设定项的值进行初始化,并且引用绑定到初始值设定项所引用的对象:
int a1 = 5;
int a2(5); // same thing
Foo * p1 = &x;
Foo * p2(&x); // same thing
Bar & b1 = y;
Bar & b2(y); // same thing
Run Code Online (Sandbox Code Playgroud)
(但是,对于用户定义类型,直接初始化和复制初始化之间存在区别,尽管这是一种微妙的区别,通常并不重要。)