C++ 安培生;在构造函数中使用const

C++ 安培生;在构造函数中使用const,c++,pass-by-const-reference,C++,Pass By Const Reference,有人能告诉我为什么我们通常把const和&放在构造函数中传递的某个对象上吗 Book::Book(const Date &date); 我在这里遇到的困惑是,通常在some函数中使用&符号,因为值是通过引用传递的,并且函数中该变量发生的任何更改都应该在以后反映出来。但另一方面,康斯特说,不能对该变量赋值 如果有人对此有什么好主意,请告诉我原因。最常见的替代方法是按值传递: Book::Book(Date date); 当传递的参数已经是日期时,通过常量引用传递可防止复制参数日期。复制

有人能告诉我为什么我们通常把const和&放在构造函数中传递的某个对象上吗

Book::Book(const Date &date);
我在这里遇到的困惑是,通常在some函数中使用&符号,因为值是通过引用传递的,并且函数中该变量发生的任何更改都应该在以后反映出来。但另一方面,康斯特说,不能对该变量赋值


如果有人对此有什么好主意,请告诉我原因。

最常见的替代方法是按值传递:

Book::Book(Date date);
当传递的参数已经是
日期
时,通过常量引用传递可防止复制参数
日期
。复制对象可能是不必要的,执行成本可能会很高,或者可能会导致切片对象(以及不正确的结果)


“切片”基本上是通过复制到对象的基础来降级对象的类型。对于多态类型,这实际上可以更改其行为,因为参数将被复制为其基(
Date
),然后对其多态接口的调用将不同,因为实现已更改(例如,其虚拟方法将改为使用基的实现).

常量引用是一种将数据传递给类的方法,无需将数据复制到本地副本,并且仍然保证函数不会修改原始对象。

这样做是为了避免不必要的副本。以以下代码为例:

Book::Book(Date date):
date_(date)
{
}
调用此构造函数时,它将复制
date
两次,一次是在调用构造函数时,一次是在将其复制到成员变量中时

如果您这样做:

Book::Book(const Date &date):
date_(date)
{
}

日期
仅复制一次。它本质上只是一种优化。

它通常是针对输入参数的性能优化。如果省略“&”,则参数将被值接受,并且在传递给函数之前必须复制输入对象。通过引用传递将绕过副本。

这意味着您通过引用传递对象(如您所述),但对象本身无法从函数中更改(在本例中为ctor)

原因可能是:

  • 您不希望复制完整对象,以提高代码的效率
  • 您不希望意外更改传入的对象
  • 您希望能够对未命名的临时对象使用该函数
  • 您希望能够传递从注释类型派生的对象(在本例中为
    Date
关于第三点,请考虑:

Book b(Date());

在C++中,当一个函数的参数类型有点像“代码> const类型和”,你所做的是允许用户通过引用传递一些值——一个指向该值的指针隐式传递进去,但是为了便于使用,编译器允许你把它当作一个值对待。p> 在某些情况下,编译器还可以对其进行优化,以便根本不使用指针,并且函数可以直接引用值的内存


使用
const
的原因是为了保护您自己,避免更改用户不希望您更改的内存,并且如果用户传入一个const变量,它仍然可以工作。

我认为“保存一个副本”的措辞可能有点混乱(如“保留一个副本”)。在我意识到你的意思是“防止复制”之前,我仔细考虑了一下。是否会有这样的情况,在
Book::Book(const-Date)
上使用
Book::Book(const-Date&Date)
?i、 e.是否直接传递对象(省略符号),但作为
常量
是否首选?@akevit我只考虑有助于可疑设计的案例;e、 g.意外的复制语义、不及物常量、在可能出现别名的内存中踮起脚尖、移动常量对象。当然,有些人会使用const值,当类型的复制成本(接近)为零时——这很好。您不能将by value传递给copy构造函数,因为要传递by value,您必须创建一个副本,你不能复制,因为这需要调用复制构造函数,它需要一个复制构造函数,这个复制构造函数包含了符号,纯粹是为了优化?例如,
Book::Book(const-Date和Date)
将传递对象的引用并阻止对原始对象的更改,然而
Book::Book(const-Date)
将传递实际的原始对象,但也阻止更改?@akevit请参阅关于您的问题。