【发布时间】:2019-04-11 02:39:46
【问题描述】:
我正在尝试理解以下代码的行为
/* code block 1 */
#include <iostream>
class A
{
private:
int value;
public:
A(int n) { std::cout << "int n " << std::endl; value = n; }
A(const A &other) { std::cout << " other " << std::endl; value = other.value; }
// A (A &&other) { std::cout << "other rvalue" << std::endl; value = other.value; }
void print(){ std::cout << "print " << value << std::endl; }
};
int main(int argc, char **argv)
{
A a = 10;
A b = a;
b.print();
return 0;
}
当我编译上面的代码时,它可以正常工作
/* code block 2 */
g++ -std=c++11 t.cpp
./a.out
int n
other
print 10
当我从复制构造函数中删除 const 时
/* code block 3 */
class A
{
...
A(int n) { std::cout << "int n " << std::endl; value = n; }
A(A &other) { std::cout << " other " << std::endl; value = other.value; }
// A (A &&other) { std::cout << "other rvalue" << std::endl; value = other.value; }
}
编译器不会编译
/* code block 4 */
t.cpp:19:5: error: no viable constructor copying variable of type 'A'
A a = 10;
^ ~~
t.cpp:9:4: note: candidate constructor not viable: no known conversion from 'A' to 'int' for 1st argument
A(int n) { std::cout << "int n " << std::endl; value = n; }
^
t.cpp:10:4: note: candidate constructor not viable: expects an l-value for 1st argument
A(A &other) { std::cout << " other " << std::endl; value = other.value; }
从结果t.cpp:9:4看来,编译器试图将A转换为int,但代码是A a = 10;,如果我是编译器,我要么
尝试从整数10初始化一个类型为A的临时变量,然后使用复制构造函数A(A &other)初始化a
直接用构造函数A(int)初始化a
我对 t.cpp:9:4
的编译器输出感到困惑从输出 t.cpp:10:4,编译器说它需要一个左值复制构造函数,所以我将代码更改为
/* code block 5 */
class A
{
...
A(int n) { std::cout << "int n " << std::endl; value = n; }
A(A &other) { std::cout << " other " << std::endl; value = other.value; }
A (A &&other) { std::cout << "other rvalue" << std::endl; value = other.value; }
}
当我按照提示定义右值复制构造函数时,输出显示未调用右值复制构造函数
/* code block 6 */
g++ -std=c++11 t.cpp
int n
other
print 10
问题:
- (在代码块 3 中)为什么我不能从复制构造函数中删除 const?
- (在代码块 4 -> t.cpp:9:4 中)为什么编译器会尝试从 'A' 转换为 'int'?
- (在代码块 5 中)编译器说它需要一个右值复制构造函数(来自代码块 4 -> t.cpp:10:4),所以我定义了一个,但运行输出显示右值复制构造函数是没叫,为什么?
【问题讨论】: