复制构造函数中的const和非const有何区别?

3

当我写我的复制构造函数时:(HocSinh是一个类)

HocSinh::HocSinh(HocSinh &a)
{
    hoTen = a.hoTen;
    diemVan = a.diemVan;
    diemToan = a.diemToan;
}

那么:

HocSinh hocSinh("abc", 1, 2);
vector <HocSinh> dsHSCanTim;
dsHSCanTim.push_back(hocSinh);

我得到了一个错误:“没有可用的复制构造函数或复制构造函数被声明为'explicit'”。但是当我写下以下内容时:
HocSinh::HocSinh(const HocSinh &a)
{
    hoTen = a.hoTen;
    diemVan = a.diemVan;
    diemToan = a.diemToan;
}

没有错误。 请问有人能为我解释一下吗?感谢大家,如果我的英语很糟糕,请见谅。


1
如果HocSinh是你的类的名称,那你为什么要执行dsHSCanTim.push_back(HocSinh);push_back需要一个HocSinh对象。 - P0W
一般而言,拷贝构造函数应该通过const引用来接受参数,除非有充分的理由使其不能为const。 - T.C.
抱歉,它是:HocSinh hocSinh("abc", 1, 2); 并且 push_back(hocSinh)。 - Phùng Khánh Hiên
通常情况下,您应该在可能的情况下使用 const。您的复制构造函数不会修改其参数,因此它可以是 const,因此应该是 const。这确保它可以接受 const 和非 const 对象。 - Oktalist
1个回答

4

由于std :: vector :: push_back的定义如下:

void push_back (const value_type& val);
void push_back (value_type&& val);

对于像 hocSinh 这样的左值,std::vector::push_back 模板将使用第一个。在 std::vector::push_back 的实现内部,将使用复制构造函数在由 std::vector 分配的内存段中构建对象。实现必须使用 const value_type& val 作为此复制的源,因此需要具有带有 const 签名以接收 val 的复制构造函数。

1
这并没有解释为什么需要一个带有常量左值引用参数的复制构造函数。 - juanchopanza
@juanchopanza OP问为什么应该有const,如果你想在实现void push_back(const value_type& val);的过程中将val用作函数参数,那么函数必须假定一个const参数,这是显而易见的。 - WiSaGaN
这并不完全明显。简短的解释可以使答案更好。 - juanchopanza

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接