与号和与常量在构造函数中
Ampersand & with const in constructor
有人能告诉我为什么我们通常使用const和&例如,在构造函数中传递一些对象。
Book::Book(const Date &date);
我在这里的困惑是,通常&在some函数中使用sign是因为该值是通过引用传递的,函数中该变量发生的任何更改都应该在之后反映出来。但另一方面,const表示不能对该变量进行赋值。
如果有人对此有什么好主意,请告诉我原因。
这样做是为了避免不必要的复制。以以下代码为例:
Book::Book(Date date):
date_(date)
{
}
当您调用此构造函数时,它将复制date
两次,一次在您调用构造函数时,另一次在将其复制到成员变量中时。
如果你这样做:
Book::Book(const Date &date):
date_(date)
{
}
date
只复制一次。它本质上只是一个优化。
最常见的替代方法是按值传递:
Book::Book(Date date);
当传递的参数已经是Date
时,通过const引用传递可以防止复制参数date
。复制对象可能是不必要的,执行成本可能很高,或者可能导致对象切片(以及不正确的结果)。
"Slicing"基本上是通过复制到对象的基对象来降级对象的类型。对于多态类型,这实际上可以改变其行为,因为参数将被复制为其基(Date
),然后对其多态接口的调用将不同,因为实现已经改变(例如,其虚拟方法将使用基的实现)。
这意味着您通过refence传递对象(正如您所指出的),但对象本身不能从函数(本例中为ctor)更改。
原因可能是:
- 您不想复制完整的对象,以提高代码的效率
- 您不希望意外更改传入的对象
- 您希望能够将函数与未命名的临时对象一起使用
- 您希望能够传递从注释类型派生的对象(在本例中为
Date
)
关于第三点,请考虑:
Book b(Date());
这通常是对输入参数的性能优化。如果省略"&"参数被值接受,并且输入对象在传递给函数之前必须被复制。通过引用传递将绕过副本。
在c++中,当函数的参数类型类似于const Type&
时,您所做的是允许用户通过引用传递中的某个值-指向该值的指针是隐式传递的,但为了便于使用,编译器允许您将其视为值。
在某些情况下,编译器还可以对其进行优化,从而完全不使用指针,并且函数可以直接引用值的内存。
使用const
的原因是为了保护您自己不更改用户不希望您更改的内存,并且如果用户传入常量变量,它也可以继续工作。
常量引用是一种将数据传递给类的方法,而无需将数据复制到本地副本,并且仍然保证原始对象不会被函数修改。
- constexpr构造函数需要常量成员函数时出现问题
- C++17 使用驱动类常量作为基类构造函数的参数来初始化基类构造函数
- C++ 常量正确性/缺少支持常量和非常量实例的类的常量构造函数
- 如何在使用 Qt5 构造函数时将非常量参数修改为常量参数?
- 通过从构造函数中的'this'复制的指针改变常量对象
- 为什么编译器在使用"无常量复制构造函数"时抱怨?
- 为什么定义复制构造函数会给我错误:无法将类型 'obj&' 的非常量左值引用绑定到类型为"obj"的右值?
- C++ 中常量属性的初始化构造函数错误
- 带有常量指针的矢量构造函数示例
- 调用构造函数与将内联常量定义为默认参数
- C++自动生成的具有常量和非常量引用的复制构造函数
- C++ 具有常量数组和initializer_list的重载构造函数
- 为什么在这种情况下调用非常量右值移动构造函数?
- 在可变参数构造函数中初始化常量数组
- 委派复制构造函数和常量数据初始化
- 为什么可以将左值传递到采用常量引用右值的构造函数中?
- CPP/C 中的常量用法和结构构造函数中的澄清
- 初始化类构造函数中的常量
- 与 map 一起使用时复制构造函数常量错误
- 提升::任何构造函数 - 常量类型重载分辨率