int a = 0 and int a(0) differences
Possible Duplicate:
Is there a difference in C++ between copy initialization and direct initialization?
我刚开始学习C++。
为了用一个值初始化一个变量,我遇到了
和
这让我很困惑。我能知道哪条路最好吗?
- 对于像int这样的内置数据类型,两者都是相同的。对于自定义类,它们可能意味着不同。
- 我不会提"int a 0",以免增加混淆:)
- @j99那么,int a{0}与定义大小为1的整数对象数组并将其赋值为0类似吗?
- 不,这是新的C++ 11方式来初始化任何东西。在本例中,它与"int a(0)"相同。
int a = 0;和int a(0);对机器生成的代码没有影响。它们是一样的。
以下是在Visual Studio中生成的程序集代码
1 2
| int a = 10; // mov dword ptr [a],0Ah
int b(10); // mov dword ptr [b],0Ah |
- 我喜欢汇编代码中显示的示例。
- 但是,仅仅因为生成的代码是相同的,并不意味着语言特性是相同的。试图通过黑盒方法学习语言,如"运行程序"和/或"检查程序集"通常会导致大量的误解。
- @seejay char c = 10;生成什么机器代码?我很好奇char和int是否相同…
- @Luchiangrigore我刚测试过它是move byte ptr , 0Ah,如果是8 bits it's byte,16 bit => word,32 bit => dword,64 bit => qword。
- 那么一辆unsigned int怎么样?(也许我最初给出了错误的例子,关键是机器代码证明不了什么)
- @是的,你是对的,在高层次上,这个概念可能意味着不同的事情。我知道在类类型和原始类型中,它们是不同的。有时我更喜欢用低级的方式理解它,例如使用汇编代码或中间代码。
- 有关详细说明,请参阅stackoverflow.com/questions/1051379/…
它们都是一样的,所以没有一种"最佳方式"。
我个人使用
因为我发现它更清晰,在实践中应用更广泛。
这适用于类型为int的代码。对于类类型,第一个是复制初始化,而另一个是直接初始化,因此在这种情况下,它会有不同。
- 对于类类型B B(A);和B B=A;实际上是相同的,并且都使用复制构造函数初始化。所以没什么不同。b b;b=a;使用assign operator,则完全是另一种情况。
- @大牛没有,他们没有。
- @大牛见stackoverflow.com/questions/11222076/…
- @卢奇昂:你是埃多克斯的野兽(0)。你的答案是very clear和to the point。谢谢你所做的一切。
- #包括A类公共:A()125125123\公共:B()St::cout<"b ctr";125; B(const A&;)St::cout<"b ctr with a";125; B&;opera=(const A&;)St::cout<<"b operator=with a"with a"b opera员=with a";return"b opera员=with a";return";return"b操作员=with a ;//输出为b ctr,带a for两个电话,怎么不一样?
- 来自en.wikipedia.org/wiki/copy_constructor"x b=a;//如果定义了任何复制构造函数,则有效"
- 看起来它依赖于编译器,所以可能有些仍然创建临时对象,而不是直接调用复制构造函数。
- @戴牛:你答应的复制建设者在哪里?首先,B(const A&)不是一个复制构造函数。然而,您最初说"两者都使用复制构造函数"。你的例子与你自己的陈述相矛盾。其次,A a; B b(a);和A a; B b = a的区别在于后者实际上使用了B的复制构造函数(除非经过优化),而前者没有。
从实践的角度来看:我只使用int a = 0;。
可以允许使用int a(0),但在实践中不能单独使用。
我认为这不应该在你的层面上打扰你,但让我们更进一步。
假设a是一个类,而不是一个int。
1 2 3 4 5 6 7 8
| class Demo{
public:
Demo(){};
Demo(int){};
};
Demo a;
Demo b(a);
Demo c = a; // clearly expressing copy-init |
在这个例子中,b(a)和c=a都这样做,我不鼓励您使用第一个解决方案。我的理由是,这看起来类似于c(2),这是一个由论点构成的结构。
此括号样式初始化只有两种有效用途:
- 初始化列表(如果demo有int数据成员data),
- 新的:Demo *p=new Demo(a); // copy constructing a pointer。
- 第三个用例将创建一个模板对象,其中=可能被重载,也可能不被重载。
没有最好的办法。对于标量类型(如示例中的int),两种形式具有完全相同的效果。
为了支持类和非类类型的统一直接初始化语法,引入了非类类型的int a(0)语法,这在类型无关(模板)代码中非常有用。
在非模板代码中,不需要int a(0)。完全取决于您是想使用int a(0)语法,还是更倾向于使用更传统的int a = 0语法。他们都做同样的事情。在我看来,后者更具可读性。
就这么简单。(好吧,几乎-有一些事情你不能命名你的变量,我们将在下一节讨论)
还可以在声明时为变量赋值。当我们使用赋值运算符(等号)给变量赋值时,它被称为显式赋值:
1
| int a= 5; // explicit assignment |
还可以使用隐式赋值将值赋给变量:
1
| int a(5); // implicit assignment |
即使隐式赋值看起来很像函数调用,编译器也会跟踪哪些名称是变量,哪些是函数,以便正确地解析它们。
- 这不是所谓的分配。赋值是C++术语中的一个保留术语,具有严格定义和非常具体的含义。将初始化称为"赋值"只会造成不必要的混淆。这两种初始化语法形式的恰当术语是直接初始化和复制初始化。
- class A public:A(int)class B public:B(const A&;)b b1(10);b b2=20;//编译并运行。如果需要显式的,那么应该在声明中像显式的a(int)
在教科书和文献中,一种是直接初始化,另一种是复制初始化。但是,在机器代码方面,没有区别。
区别在于,当您明确希望()初始化只接受一个参数时,例如:
你可以:int a = 44 + 2;但你不能:int a(44) + 2;
- 但是你可以这样做:积分A(44+2);所以这不是一个显著的区别。