C ++ - 关于内存管理的问题

时间:2010-12-25 11:02:00

标签: c++ memory-management

我有以下课程:

class StringHolder
{
public:
    StringHolder(std::string& str)
    {
        m_str = &str;
    }

private:
    std::string* m_str;
};

并拥有以下字符串对象(str),大小为1,024KB:

char c = 'a';
unsigned long long limit = 1024 * 1024;
std::stringstream stream;
for(int i = 0; i < limit; i++)
{
    stream << c;
}
std::string str = stream.str();

每当我使用字符串初始化StringHolder类时,不会复制该字符串。那是因为我使用了参考文献&amp;指针,但我不确定我是否正确使用它们:\

问题:我是否使用了参考文献&amp;指针正确吗?

2 个答案:

答案 0 :(得分:5)

正确的实现应该是

class StringHolder
{
public:
    StringHolder(const std::string& str) //note const
                 : m_str(str){}          //use initialization list

private:
    std::string m_str; //no need to make it a pointer
};

答案 1 :(得分:1)

假设已知字符串的生命周期比将引用它的对象寿命更长,并且该对象不需要修改字符串,那么您可以对构造函数中的字符串进行常量引用,存储在:

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

使用此解决方案,不会复制字符串的内容,但对原始字符串的任何更改都将影响从引用中看到的内容。此外,这不允许您更改构造后引用的字符串。如果您需要重新设置引用,则必须使用指针:

class StringHolder {
   std::string const * str;
public:
   StringHolder( std::string const & s ) : str(&s) {}
   void reset( std::string const & s ) {
      str = &s;
   }
};

您需要存储指针而不是引用这一事实是一个实现细节,因此您可以(就像我一样)将其隐藏起来,或者您可以更改接口以通过指针获取字符串以使其成为可能更明确(我更喜欢前者,但后者具有自我记录的效果:更清楚的是必须考虑生命周期)。

另请注意,使用如图所示的实现,可以使用临时来初始化/设置字符串,从而导致未定义的行为:临时死亡,引用指向无处。