2

我有一个具有私有字符串指针的类。此类还有一个公共方法,该方法取消引用该字符串指针并将结果字符串返回给调用者。我的问题是:保存取消引用字符串的内存会发生什么?

这是我的代码:

#include <iostream>
#include <string>

class myclass
{
    private:
        std::string *_name;

    public:
        myclass()
        {
            this->_name = new std::string("my name");
        }

        ~myclass()
        {
            delete this->_name;
        }

        std::string getName()
        {
            return *this->_name;
        }
};

void main()
{
    myclass m;
    {
        std::string str = m.getName(); //what happens to this memory?
        std::cout << str << std::endl;
    } //str deleted here (I think)
    //here, the m._name pointer hasn't yet been deleted
}

在我的主函数中,变量str被分配了取消引用的字符串。保存这个字符串的内存会发生什么?我认为内存保留在堆栈上,因此当变量超出范围时会自动“取消分配”。令我困惑的是,即使取消引用的字符串不再在范围内,私有字符串指针仍可能在范围内。变量是否str被分配了私有_name指针值的副本?

如果此代码确实在后台复制字符串,我是否应该担心性能。如果我只getName()返回_name指针而不取消引用它,我的代码会运行得更快吗?

4

2 回答 2

2

遵循“三法则”。如果您定义了以下任何一个:复制构造函数、赋值运算符、析构函数,则定义所有这些。这样就不会混淆指向字符串的指针是否被删除:您只需在相应的赋值运算符中创建一个新指针。

于 2013-09-19T19:52:32.487 回答
2

首先,您不需要指针。其次,你可以返回一个副本(就像你做的那样)或一个引用(或者如果你想坚持的话,可以返回一个指针),但是这两种方法都有利有弊:

class myclass
{
private:
    std::string _name;
public:
    myclass() : _name("my name")
    {
    }
    std::string getName1() { return _name; }
    std::string& getName2() { return _name; }
    const std::string& getName3() const { return _name; }
}

getName1按值返回。缺点是制作了一个副本,这可能会影响性能,但是在对象超出范围后返回的值可以安全使用。

getName2和之间的区别在于getName3您可以使用前者来修改类的实际成员。缺点是如果对象超出范围,则无法再使用该引用,因此您将留下一个悬空引用。优点是它更有效,因为不涉及复制。

myclass x;
std::string a = x.getName1(); // copy is made
std::string& b = x.getName2(); // no copy
                               // b is mutable
b = "something else";  //this will modify x._name
const std::string& c = x.getName3; // no copy
                                   // c is const

myclass* y = new myclass;
std::string d = x.getName1();  // copy is made
std::string& e = x.getName2(); // no copy
delete y;
d = "something else"; //legal
e = "something else"; //undefined behavior, e is a dangling reference
于 2013-09-19T19:33:54.257 回答