2011-11-19 69 views
2

假设我没有在类中指定复制构造函数和operator=,以下两个声明之间有什么区别?在堆栈中声明一个对象的两种方法之间的区别

Beatle john(paul);

Beatle john = paul;

编辑:

在对象分配,运营商=隐式调用拷贝构造函数,除非另行告知?

+0

为什么选择'john'和'paul'作为变量名和'Dog'作为类型? – Nawaz

+0

@Nawaz我改变了它(; –

+0

@Nawaz狗有什么毛病叫约翰和保罗? –

回答

7

它们是不同的语法结构。第一个是直接初始化,第二个是复制初始化。他们的行为几乎相同,只有第二要求非explicit构造。*

无论有什么用赋值运算符,如两条线都初始化

即:const int i = 4;是好的,但const int i; i = 4;不是。

*)更准确地说:如果相关的构造函数声明为explicit,则第二个版本不起作用。更一般地,因此,直接初始化,给您一个“免费”的转换:

struct Foo { Foo(std::string) {} }; 

Foo x("abc"); // OK: char(&)[4] -> const char * -> std::string -> Foo 
Foo y = "abd"; // Error: no one-step implicit conversion of UDTs 

为了解决您的编辑:了解赋值运算符,只是把它分解成部分。假设Foo有明显的operator=(const Foo & rhs)。我们可以说x = y;,它只需要rhs直接呼叫运营商是y。现在考虑这个:

x = "abc";    // error, no one-step implicit conversion 
x = std::string("abc"); // fine, uses Foo(std::string), then copy 
x = Foo("abc");   // fine, implicit char(&)[4] -> const char* -> std::string, then as above 
+0

你可以提供一个参考吗?(我只是好奇...) – xmoex

+0

@xmoex:全部在8.5节 –

2

首先是直接初始化&二是拷贝初始化。

直接初始化意味着对象使用单个(可能转换)构造初始化,并且等同于形式T t(u);

U u; 
T t1(u); // calls T::T(U&) or similar 

复印初始化表示对象被初始化使用拷贝构造,如果需要首先调用用户定义的转换之后,并且等同于表格T t = u;

T t2 = t1; // same type: calls T::T(T&) or similar 
T t3 = u; // different type: calls T::T(T(u)) 
      // or T::T(u.operator T()) or similar 

如果构造函数声明为explicit,则复制初始化不起作用。

参考文献:
This在香草萨特的GOTW进入应该是一个很好看的。


要回答你的问题编辑:
=具有取决于如何使用它不同的含义。

如果=在其中对象正被创建并同时初始化表达式中使用,然后=不被视为赋值运算符但作为复制初始化。

如果使用=将一个对象分配给另一个对象,则在之后该对象已创建,则会导致调用分配操作员。

+0

所以这意味着'甲壳虫约翰(保罗)'和'披头士约翰保罗:'等价吗? –

+1

@LeifEricson:呵?答案解释了它们是怎样**不等同于**,哪一部分答案不清楚或者让你困惑? –

+0

'T t2 = t1; //相同类型:调用T :: T(T&)或类似的''这意味着这一行调用一个拷贝构造函数,这意味着在这种情况下它们是等价的。 –

相关问题