【问题标题】:How to avoid explicitly calling a constructor when passing temporary object by reference in C++?在 C++ 中通过引用传递临时对象时如何避免显式调用构造函数?
【发布时间】:2010-11-03 17:49:55
【问题描述】:

假设我有一堂课:

class String
{
public:
     String(char *str);
};

还有两个功能:

void DoSomethingByVal(String Str);
void DoSomethingByRef(String &Str);

如果我这样调用 DoSomethingByVal:

DoSomethingByVal("My string");

编译器发现它应该创建一个临时 String 对象并调用 char* 构造函数。

但是,如果我尝试以相同的方式使用 DoSomethingByRef,我会收到“无法将参数从 'char *' 转换为 'String &'”错误。

相反,我必须显式创建一个实例:

DoSomethingByRef(String("My string"));

这会让人很讨厌。

有什么办法可以避免吗?

【问题讨论】:

    标签: c++ pass-by-reference


    【解决方案1】:

    你需要通过 const 引用来传递:

    为:

    void DoSomethingByVal(String Str);
    

    在这种情况下,编译器首先创建一个临时变量。然后将临时变量复制构造到参数中。

    为:

    void DoSomethingByRef(String const& Str);
    

    在这种情况下,编译器会创建一个临时变量。但是临时变量不能绑定到引用,它们只能绑定到 const 引用,因此无法调用您的原始函数。请注意,std::string objects 构造函数采用 const 引用是复制构造函数的参数,这就是为什么第一个版本的工作原理是临时绑定到复制构造函数的 const 引用参数。

    【讨论】:

      【解决方案2】:

      嗯,我不确定

      void DoSomethingByRef(String &Str);
      DoSomethingByRef(String("My string"));
      

      实际上会编译。右值不能绑定到对非 const 的引用(因为对非 const 的引用表明您将修改该值,而修改临时值没有意义)。你确定你没有这样做:

      String str("My string");
      DoSomethingByRef(str);
      

      如果您希望 DoSomethingByVal 采用右值,则参数必须是对 const 的引用:

      void DoSomethingByRef(const String &Str);
      

      【讨论】:

      • 允许接受右值的是 MSVC++ 脑死亡。正如您所指出的,这当然是无效的。
      • DoSomethingByRef(String("My string"));将在 vc2008 上编译
      • @hammer:回到 litb 评论:“这是 MSVC++ 脑死亡……”:)
      【解决方案3】:

      制作:

      DoSomethingByRef(const String &str);

      【讨论】:

        【解决方案4】:

        “我的字符串”不是字符串,它是一个 c 字符串,一个 char*,如果你愿意的话。您需要将该 c-string 放入 String 对象中,然后您可以通过引用传递新的 String 对象。

        另外一点,你已经传递了一个 char*... 它非常轻量级,只是一个指针。为什么要担心通过引用传递新对象?只需从堆中的构造函数中分配一个新对象并将 c-string 复制到其中。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-07-07
          • 1970-01-01
          • 2019-03-02
          • 2011-06-11
          • 1970-01-01
          • 1970-01-01
          • 2013-11-13
          • 2017-09-11
          相关资源
          最近更新 更多