注册 登录
编程论坛 C++教室

这道题为什么参数里加上const就对了?

青蝶 发布于 2018-09-15 15:23, 1851 次点击
#include <iostream>
using namespace std;
class Sample {
public:
    int v;
    Sample(int n=5){v=n;}
    Sample(const Sample &t){
        v=t.v+2;
    }
};
void PrintAndDouble(Sample o)
{
    cout << o.v;
    cout << endl;
}
int main()
{
    Sample a(5);
    Sample b = a;
    PrintAndDouble(b);
    Sample c = 20;   //上面红色那个const不加的话,这一句会报错,求大佬解释一下
    PrintAndDouble(c);
    Sample d;
    d = a;
    cout << d.v;
    return 0;
}



[此贴子已经被作者于2018-9-15 15:24编辑过]

5 回复
#2
Jonny02012018-09-15 18:13
Sample(int n=5);
相当于将一个 int 转换成了你写的 Sample 类型
Sample c = 20;
就相当于
Sample c = Sample(20);
这里用到了
Sample(const Sample &t);
复制建构函数
而 Sample(20) 是一个右值, 他是不可以被绑定到左值引用上的
没有 const 限定的函数 Sample(Sample &) 中的 Sample 是一个左值引用, 所以函数匹配失败, 出现编译错误
但是 C++ 中有一个例外的是, 为了延长右值的生命周期, 右值可以被绑定到被 const 限定的左值引用上, 所以你加上 const 就不会出错了
或者使用 C++ 11 的右值移动, 将其改成
Sample(Sample &&t);
或者在构造函数之前加上 explicit 声明禁止 int 被隐含地转换
#3
Jonny02012018-09-15 18:14
不过 Clang 好像有特别的实现
我去掉 const 之后 Clang 仍然可以编译通过
@rjsp
#4
rjsp2018-09-15 21:31
回复 3楼 Jonny0201
Sample c = 20;
就相当于
Sample c = Sample(20);


接着,又相当于 Sample c(20);
C++(后来)规定了即使上述省略掉的步骤中存在“副作用”也应当视而不见地省略掉。
但没规定在上述省略掉的步骤中如果若存在语法错误怎么办?
gcc6及之前的版本,就报错;gcc7及之后,不管了,就通过。
#5
Jonny02012018-09-16 00:29
回复 4楼 rjsp
thx
看起来学 C++ 还是免不了要看标准
#6
青蝶2018-09-16 21:29
谢谢~
1