为啥我们使用 const 和 reference 作为参数来复制构造函数?

Posted

技术标签:

【中文标题】为啥我们使用 const 和 reference 作为参数来复制构造函数?【英文标题】:Why do we use const and reference for arguments to copy constructors?为什么我们使用 const 和 reference 作为参数来复制构造函数? 【发布时间】:2020-11-05 14:04:45 【问题描述】:

考虑以下示例:

#include<iostream> 
using namespace std;

class Point

private:
    int x, y;
public:
    Point(int x1, int y1)  x = x1; y = y1; 

    // Copy constructor 
    Point(const Point& p2)  x = p2.x; y = p2.y; 

    int getX()  return x; 
    int getY()  return y; 
;

int main()

    Point p1(10, 15); 
    Point p2 = p1; 


    cout << "p1.x = " << p1.getX() << ", p1.y = " << p1.getY();
    cout << "\np2.x = " << p2.getX() << ", p2.y = " << p2.getY();

    return 0;

我们注意到Point(const Point&amp; p2); 是一个复制构造函数。为什么我们使用const 关键字,为什么我们使用引用?我们为什么不使用Point(Point p2);

【问题讨论】:

一个原因是临时对象不能绑定到非常量引用。 注意:我已经恢复了 OP:s 编辑,它添加了一个完全独立的问题。 OP:请仅针对每个线程提出问题。 【参考方案1】:

为什么我们使用 const 关键字 [...] ?

您不需要对类复制构造函数使用const-qualified(甚至是cv-qualified)参数;引用cppreference / Copy Constructors:

T的复制构造函数是一个非模板构造函数,它的第一个参数是T&amp;‍const T&amp;‍volatile T&amp;‍const volatile T&amp;‍,或者没有其他参数,或者剩下的参数都有默认值。

但如果复制构造函数需要变异它用于复制的对象,那将是非常不寻常的

#include <iostream>

struct A 
    int x;
    A(int x_) : x(x_) 
    A(A& other) : x(other.x)  ++other.x; 
;

int main() 
    A a142;  // a1.x is 42.
    A a2(a1);  // a2.x is 42, AND a1.x is 43
    std::cout << a1.x << " " << a2.x;  // 43 42

此外,非const 引用不能绑定到右值以延长它们的生命周期,这意味着这样的复制构造函数不能用于从临时对象复制初始化。即,以下(常见情况)格式正确:

struct A 
    int x;
    A(int x_) : x(x_) 
    A(const A& other) : x(other.x)  
    static A create()  return 12; ;
;

int main() 
    A a1(A::create());  // OK.

而以下是格式错误的(在 C++17 中保证复制省略之前):

struct A 
    int x;
    A(int x_) : x(x_) 
    A(A& other) : x(other.x)  
    //^^ non-const ref cannot bind to rvalue.
    static A create()  return 12; ;
;

int main() 
    // Ill-formed before C++17 and guaranteed copy elision.
    A a1(A::create());  // (C++14) error: no matching constructor for initialization of 'A'


[...] 我们为什么要使用引用?

如果语言实际上允许声明一个复制构造函数是通过值而不是引用来获取其参数(例如,复制源对象),而无需对语言进行任何其他更改,只需传递从对象复制到复制构造函数(在实现它之前!)将需要从调用站点复制对象。因此,这样的复制构造函数需要在定义如何复制对象之前复制对象,这是一种自然不合理的递归逻辑。

【讨论】:

以上是关于为啥我们使用 const 和 reference 作为参数来复制构造函数?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我们不能定义一个指向 int 指针的低 + *** const 指针?

为啥我们不能在 TypeScript 类中定义一个 const 字段,为啥静态只读不起作用?

为啥对按值传递的参数使用 const? [复制]

C++ pass-by-non-const-reference 方法在 pass-by-const-reference 方法中

为啥当我们有 const 引用时创建临时对象?

为啥 C++ 复制构造函数必须使用 const 对象?