2

プライベート文字列ポインターを持つクラスがあります。このクラスには、その文字列ポインターを逆参照し、結果の文字列を呼び出し元に返す public メソッドもあります。私の質問はこれです: 逆参照された文字列を保持するメモリはどうなりますか?

これが私のコードです:

#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

「3のルール」に従ってください。コピー コンストラクタ、代入演算子、デストラクタのいずれかを定義する場合は、それらすべてを定義します。そうすれば、文字列へのポインターが削除されたかどうかで混乱することはありません。対応する代入演算子で新しいポインターが作成されるだけです。

于 2013-09-19T19:52:32.487 に答える
2

まず、ポインタは必要ありません。第 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 に答える