5

我有一个这样的课程。我想对字符串使用引用,但它不起作用。我怎样才能使用 string& ?

#include <string>
using namespace std;
class T
{
public:
    T(string& s);
private:
    string s;
};

T::T(string& s)
{
    this->s = s;
}
int main(void)
{
    T t("Test Object");
    return 0;
}

错误:“T::T(std::string &)”:无法将参数 1 从“const char [12]”转换为“std::string &”

4

5 回答 5

6

使用const

class T
{
public:
    T(const string& ss);
private:
    string s;
};

T::T(const string& ss) : s(ss)
{
}

"Test Object"const string在传递给 的构造函数之前将被构造为 a T,因此构造函数必须接受 a const string

于 2013-03-12T11:59:19.030 回答
2

您没有传入 std::string。正如它所说,它不能从 const char 数组转换为 string-ref。将构造函数更改为采用 const-ref 即可。这是因为必须从 char 数组创建一个临时字符串,并且您只能对临时对象进行 const 引用以防止混淆(如果您修改临时字符串,更改将被丢弃,所以语言阻止你这样做)。

于 2013-03-12T12:00:19.060 回答
2

C++98/03中,如果您有一个复制成本不高的类(例如,anint或 adouble复制成本低,则 astd::string不是,因为它的复制可能涉及分配新的堆内存,将字符从源复制到目标等),那么规则是通过const引用 const std::string&传递:

class T
{
public:
    T(const string& s); // <--- const string&
private:
    string m_s;
};

然后在构造函数中执行:

T::T(const string& s)
   : m_s(s)
{}

然而,在C++11中,移动语义可用,新规则似乎是:如果您需要一个副本(并且对象移动起来很便宜,通常应该如此),按值传递并从值移动

T::T(string s)             // pass by value
   : m_s( std::move(s) )   // and move from the value
{}

(最好的办法是提供几个重载,传递const &和传递值,但可能这并不一定适用于所有应用程序,但只有在您需要压缩性能时才如此。)

注意,当不需要拷贝,只需要观察参数时,通常的C++98/03 pass by const &rule仍然有效。

于 2013-03-12T12:20:47.913 回答
1

您定义的构造函数采用std::string引用:

T::T(std::string& s)
{
    this->s = s;
}

因此,最直接的做法是创建一个std::string对象,该对象将传递给此构造函数:

std::string s("Test Object");
T t(s);

但是由于您的构造函数不会更改std::string您传递给它的值(它只是用于设置 的T数据成员的值),因此您应该传递constreference: T::T(const string& s)。此外,与其让数据成员s被构造并稍后为其分配另一个字符串,不如直接在初始化列表中构造该成员:

T::T(const std::string& str) : s(str) { }
于 2013-03-12T12:18:00.997 回答
0

引用需要使用构造函数的初始化列表进行初始化。将您的构造函数更改为:

T::T(string& s) : s(s)
{
}

另外定义您的成员s以便std::string& s能够参考。

也许更改 s 的名称以避免歧义。

请参阅SO 上的此条目

于 2013-03-12T11:58:53.070 回答