Item 42. Variable Initialization is it?

本文解析了C++中四种不同变量初始化的方式:默认初始化、直接初始化、复制初始化及一个易混淆的函数声明案例。通过实例对比了不同初始化方式的区别,并提供了一条准则来帮助选择最佳实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

This first problem highlights the importance of understanding what you write. Here we have four simple lines of code, no two of which mean the same thing, even though the syntax varies only slightly.

What is the difference, if any, between the following? (T stands for any class type.)

T t; 
T t();
T t(u);
T t = u;
 
I l@ve RuBoardPrevious Section Next Section

Solution

graphics/bulb_icon.gif

This puzzle demonstrates the difference between three kinds of initialization: default initialization, direct initialization, and copy initialization. It also contains one red herring that isn't initialization at all. Let's consider the cases one by one.

T t; 

This is default initialization. This code declares a variable named t, of type T, which is initialized using the default constructor T::T().

T t(); 

A red herring. At first glance, it may look like just another variable declaration. In reality, it's a function declaration for a function named t that takes no parameters and returns a T object by value. (If you can't see this at first, consider that the above code is no different from writing something like int f(); which is clearly a function declaration.)

Some people suggest writing "auto T t();" in an attempt to use the auto storage class to show that, yes, they really want a default-constructed variable named t of type T. Allow me license for a small rant here. For one thing, that won't work on a standard-conforming compiler; the compiler will still parse it as a function declaration, and then reject it because you can't specify an auto storage class for a return value. For another thing, even if it did work, it would be wrong-headed, because there's already a simpler way to do what's wanted. If you want a default-constructed variable t of type T, then just write "T t;" and quit trying to confuse the poor maintenance programmers with unnecessary subtlety. Always prefer simple solutions to cute solutions. Never write code that's any more subtle than necessary.

T t(u); 

Assuming u is not the name of a type, this is direct initialization. The variable t is initialized directly from the value of u by calling T::T(u). (If u is a type name, this is a declaration even if there is also a variable named u in scope; see above.)

T t = u; 

This is copy initialization. The variable t is always initialized using T's copy constructor, possibly after calling another function.

Common Mistake

graphics/commonmistake_icon.gif

This is always initialization; it is never assignment, and so it never calls T::operator=(). Yes, I know there's an "=" character in there, but don't let that throw you. That's just a syntax holdover from C, not an assignment operation.


Here are the semantics:

  • If u is of type T, this is the same as writing "T t(u);" and just calls T's copy constructor.

  • If u is of some other type, then this has the meaning "T t( T(u) );"梩hat is, u is first converted to a temporary T object, and then t is copy-constructed from that. Note, however, that in this case the compiler is allowed to optimize away the "extra" copy and convert it to the direct-initialization form (that is, make it the same as "T t(u);"). If your compiler does this, the copy constructor must still be accessible. But if the copy constructor has side effects, then you may not get the results you expect, because the copy constructor's side effects may or may not happen, depending on whether the compiler performs the optimization or not.

Guideline

graphics/guideline_icon.gif

Prefer using the form "T t(u);" instead of "T t = u;" where possible. The former usually works wherever the latter works, and has other advantages梖or example, it can take multiple parameters.


  •  
   
I l@ve RuBoardPrevious Section Next Section
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值