【问题标题】:Ampersand & with const in constructor与号 & 构造函数中带有 const
【发布时间】:2012-04-17 11:05:51
【问题描述】:

有人能告诉我为什么我们通常将 const 和 & 与一些在构造函数中传递的对象放在一起。

Book::Book(const Date &date);

我在这里遇到的困惑是,在某些函数中通常使用 & 符号,因为值是通过引用传递的,并且函数中该变量发生的任何更改都应在之后反映。但另一方面 const 表示不能对该变量进行赋值。

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

【问题讨论】:

  • 您不能将值传递给复制构造函数,因为要通过值传递,您必须进行复制,并且您不能进行复制,因为这将涉及调用需要复制的复制构造函数复制构造函数

标签: c++ pass-by-const-reference


【解决方案1】:

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

Book::Book(Date date);

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

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

【讨论】:

  • 我认为“保存副本”的措辞可能有点令人困惑(如“保留副本”)。在我意识到您的意思是“防止复制”之前,我采取了双重措施
  • 会不会出现Book::Book(const Date date) 会被Book::Book(const Date &date) 使用的实例?即直接传递对象(省略&符号)但作为const 曾经首选?
  • @akevit 我只考虑有助于可疑设计的案例;例如意外的复制语义,不传递的 const,在潜在的别名内存中小心翼翼,移动 const 对象。当然,有些人会在类型成本(旁边)不需要复制时使用 const 值——这很好。
【解决方案2】:

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

【讨论】:

  • 那么包含与号纯粹是为了优化吗?例如Book::Book(const Date &date) 将传递对象的引用并防止更改原始对象,但是Book::Book(const Date date) 将传递实际的原始对象但也防止更改?
  • @akevit 关于您的问题,请参阅this question and answers
【解决方案3】:

这样做是为了避免不必要的复制。以下面的代码为例:

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

当您调用此构造函数时,它将复制date 两次,一次是在您调用构造函数时,一次是在您将其复制到成员变量时。

如果你这样做:

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

date 只被复制一次。它本质上只是一个优化。

【讨论】:

    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

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

      原因可能是:

      • 您不想复制完整的对象,以提高您的代码效率
      • 您不想意外更改传入的对象
      • 您希望能够将该函数用于未命名的临时对象
      • 您希望能够传递从指定类型派生的对象(在本例中为Date

      对于第三点,请考虑:

      Book b(Date());
      

      【讨论】:

        【解决方案6】:

        在 C++ 中,当您有一个函数的参数类型类似于 const Type& 时,您所做的是允许用户在 通过引用 中传递一些值 - 指向该值的指针是隐式传入的,但为了便于使用,编译器允许您将其视为一个值。

        在某些情况下,编译器还可以对其进行优化,使得根本不用指针,函数可以直接引用值所在的内存。

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-11-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-09-26
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多