c ++传递字符串文字而不是const std :: string&?

时间:2010-12-06 18:44:56

标签: c++ string reference literals

我有以下代码,使用g ++编译没有警告(-Wall -pedantic)

#include <iostream>
#include <string>

using namespace std;

class Foo
{
public:
    Foo(const std::string& s) : str(s)
    { }

    void print()
    {
        cout << str << endl;
    }

private:
    const std::string& str;
};


class Bar
{
public:

    void stuff()
    {
        Foo o("werd");
        o.print();
    }
};


int main(int argc, char **argv)
{
    Bar b;
    b.stuff();

    return 0;
}

但是当我运行它时,只打印出换行符。 发生了什么?

如果我要在里面做这件事:

string temp("snoop");
Foo f(temp);
f.print();

然后它运作正常!

3 个答案:

答案 0 :(得分:21)

这种失败的原因是因为它基本上可以编入以下内容。

Foo o(std::string("wurd"));

在这种情况下,Foo值将引用一个临时对象,该对象在构造函数完成后被删除。因此它保持了死亡价值。第二个版本有效,因为它持有对具有比Foo实例更长寿命的本地的引用。

要修改此更改,请将memebr从const std::string&更改为const std::string

答案 1 :(得分:2)

发生的事情是,正在初始化引用'str',以便它指向临时arg,'s'。它与使用指针几乎相同 - 你依赖于构造函数arg的继续存在,'s'。删除临时值(在构造函数ftn返回之后),那么您的引用现在指向垃圾。

要修复,请更改str以使其成为实际的字符串对象而不是引用。

const std :: string str;

这样就会复制你的arg字符串,并且所说的副本将与你的Foo对象具有相同的生命周期。

答案 2 :(得分:0)

扩展之前给出的答案:如果要避免复制数据,可以将Foo的member和constructor参数更改为const char*

class Foo
{
public:
    Foo(const char* s) : str(s)
    { }

    void print()
    {
        cout << str << endl;
    }

private:
    const char* str;
};


class Bar
{
public:

    void stuff()
    {
        Foo o("werd");
        o.print();
    }
};


int main(int argc, char **argv)
{
    Bar b;
    b.stuff();

    return 0;
}