假设我没有在类中指定复制构造函数和operator=
,以下两个声明之间有什么区别?在堆栈中声明一个对象的两种方法之间的区别
Beatle john(paul);
和
Beatle john = paul;
编辑:
在对象分配,运营商=
隐式调用拷贝构造函数,除非另行告知?
假设我没有在类中指定复制构造函数和operator=
,以下两个声明之间有什么区别?在堆栈中声明一个对象的两种方法之间的区别
Beatle john(paul);
和
Beatle john = paul;
编辑:
在对象分配,运营商=
隐式调用拷贝构造函数,除非另行告知?
它们是不同的语法结构。第一个是直接初始化,第二个是复制初始化。他们的行为几乎相同,只有第二要求非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
你可以提供一个参考吗?(我只是好奇...) – xmoex
@xmoex:全部在8.5节 –
首先是直接初始化&二是拷贝初始化。
直接初始化意味着对象使用单个(可能转换)构造初始化,并且等同于形式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进入应该是一个很好看的。
要回答你的问题编辑:
=
具有取决于如何使用它不同的含义。
如果=
在其中对象正被创建并同时初始化表达式中使用,然后=
不被视为赋值运算符但作为复制初始化。
如果使用=
将一个对象分配给另一个对象,则在之后该对象已创建,则会导致调用分配操作员。
所以这意味着'甲壳虫约翰(保罗)'和'披头士约翰保罗:'等价吗? –
@LeifEricson:呵?答案解释了它们是怎样**不等同于**,哪一部分答案不清楚或者让你困惑? –
'T t2 = t1; //相同类型:调用T :: T(T&)或类似的''这意味着这一行调用一个拷贝构造函数,这意味着在这种情况下它们是等价的。 –
为什么选择'john'和'paul'作为变量名和'Dog'作为类型? – Nawaz
@Nawaz我改变了它(; –
@Nawaz狗有什么毛病叫约翰和保罗? –