0

假设我有一堂课:

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"));

这可能会让人讨厌。

有没有办法避免这种情况?

4

4 回答 4

9

您需要通过 const 引用传递:

为了:

void DoSomethingByVal(String Str);

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

为了:

void DoSomethingByRef(String const& Str);

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

于 2009-06-17T16:52:13.623 回答
2

嗯,我不确定是否

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

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

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

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

void DoSomethingByRef(const String &Str);
于 2009-06-17T16:52:32.937 回答
0

制作:

DoSomethingByRef(const String &str);

于 2009-06-17T16:52:47.943 回答
0

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

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

于 2009-06-17T16:55:30.500 回答