【问题标题】:C++ beginner: what is the point of using a variable by reference if using "const"?C ++初学者:如果使用“const”,通过引用使用变量有什么意义?
【发布时间】:2012-03-04 16:04:06
【问题描述】:

我想知道这个函数声明中的逻辑:

CMyException (const std::string & Libelle = std::string(),...

通过引用使用变量有什么意义?通常,当变量可能在内部被修改时,您通过引用传递变量......所以如果您使用关键字const,这意味着它永远不会被修改。

这是矛盾的。

谁能给我解释一下?

【问题讨论】:

  • @iammilind:通过 const 引用传递数字有点笨拙,复制它们要简单得多...

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


【解决方案1】:

我通常将所有内容都作为 const 传递 - 我从不修改参数,对于原始类型按值,对于自定义类型按引用。在大多数情况下,按值传递原始类型更有效 - 考虑无符号短 - 按值 2 个字节,通过引用 4-8 个字节,具体取决于指针大小。

【讨论】:

    【解决方案2】:

    实际上引用是用来避免不必要的对象复制。

    现在,要了解为什么使用const,试试这个:

    std::string & x= std::string(); //error
    

    它会给出编译错误。这是因为表达式std::string() 创建了一个不能绑定到非常量引用的临时对象。但是,临时可以绑定到const 引用,这就是需要const 的原因:

    const std::string & x = std::string(); //ok
    

    现在回到代码中的构造函数:

    CMyException (const std::string & Libelle = std::string());
    

    它为参数设置一个默认值。默认值是根据临时对象创建的。因此你需要const(如果你使用reference)。

    使用 const 引用还有一个好处:如果你有这样的构造函数,那么你可以像这样引发异常:

    throw CMyException("error"); 
    

    它从字符串文字"error" 中创建一个std::string 类型的临时对象,并且该临时对象绑定到const 引用。

    【讨论】:

    • +1 指出为什么需要“const”来绑定临时对象
    【解决方案3】:

    没有。每当您将任何变量作为引用传递时,并不总是需要在内部对其进行修改。如果变量是按值传递的,那么每当调用该函数时都会生成一个变量的副本。

    另一方面,引用变量使用相同的对象并且本质上只传递内存地址(与使用 std::string* 相同,但不能使用空内存地址除外)。因此,当您执行const std::string& x 之类的操作时,您的意思是:

    1. The passed argument will not be copied. The same object will be used as in memory.
    2. The function will absolutely not modify the object that it is handling.
    

    如果您考虑一下,当您使用引用时使用const 是有意义的,而不是其他情况。如果您要复制我传递的变量然后对其进行修改,那么我真的不在乎。但是,如果您不打算修改我传递的对象(因为您将使用相同的对象),我可以在此下严格地进一步定义我的应用程序的过程。保证。

    【讨论】:

      【解决方案4】:

      通过 const 引用传递原始类型(intchar、..)没有意义。即使是std::string,我也认为不需要。

      但是,较大的结构或类在按值传递时需要副本,因此存在开销。 const 引用模拟了按值传递的行为(外部变量未修改),但也防止了额外的复制。

      【讨论】:

      • 对于 std::string 非常推荐,这样就不会不必要地调用 CTOR 和 DTOR。
      • 我实际上在想:通过引用传递原语会比通过值传递更慢或更麻烦吗?这样做似乎是“多余的”,但对于固定调用约定也有一些话要说。
      • 通过 const 引用传递任何东西都可能被认为是过早的优化。尽管如此,“通过 const 引用传递类类型,通过值传递其他类型”的规则似乎无处不在。这是遵循它的正当理由。
      • @Ajay 通过引用传递它意味着在被调用函数中增加了一层间接性。可能比调用复制构造函数和析构函数更昂贵的东西。更不用说函数内部需要非常量副本的情况。性能提升不是系统性的——为std::string 使用 const 引用的理由就是每个人都这样做。
      • 在汇编级别,一个简单的间接调用如何比 CCTOR 和 DTOR 调用更昂贵?大多数情况下,CTOR 和 DTOR 不会被内联/优化,并且会对它们产生跳转指令 - 与“引用”相比成本太高
      【解决方案5】:

      例如,您只能使用 const 引用参数来执行此操作:

      CMyException("foo");
      

      想一想就明白了。

      【讨论】:

      • C++11 的右值引用想和你谈谈。 :)
      • @Xeo 仍然没有设法进入。但是,是的,你是对的。
      【解决方案6】:

      有些参数可能会占用相当多的内存。如果您将参数作为值传递,它将被复制并将副本传递给方法。

      将它们作为引用传递只会将指针传递给更快并为副本节省内存的方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-07-18
        • 2013-11-06
        • 2019-05-10
        • 1970-01-01
        • 1970-01-01
        • 2015-12-04
        • 1970-01-01
        • 2012-08-30
        相关资源
        最近更新 更多