5

たとえば、私の本の1つからの次のようなコード:

class HasPtr {
public:
    HasPtr(const HasPtr& h): ps(new std::string(*h.ps)), i(h.i) { }
    HasPtr(const std::string &s = std::string()): ps(new std::string(s)), i(0) { }
    HasPtr& operator=(const HasPtr&);
    ~HasPtr() { delete ps; }
private:
    std::string *ps;
    int i;
};

HasPtr& HasPtr::operator=(const HasPtr &rhs){
    auto newp = new string(*rhs.ps); // copy the underlying string
    delete ps; // free the old memory
    ps = newp; // copy data from rhs into this object
    i = rhs.i;
    return *this; // return this object
}

operator= の内部は次のようになります。

*ps = *rhs.ps
i = rhs.i
return *this;

最初にポインターを削除する必要がないため、削除するのは冗長に思えます。例外が発生した場合にオブジェクトを適切な状態のままにする方法で書かれていることは言及しましたが、それを過ぎて漏らしませんでしたが、私の代替手段でさえ処理できない例外が発生する可能性はありません。割り当てる前に最初にオブジェクトを削除する必要があるのはなぜですか?

4

2 に答える 2

5

この場合、はい、それで問題ありません。

動的に割り当てられた文字列をリークしているのではなく、再利用しています。

于 2015-08-28T00:01:48.557 に答える
4

これは私にはうまく見えます。

おっしゃる通り、std::string代入はすでに強力な例外保証を提供しているため、文字列をコピーして例外が発生した場合でも、オブジェクトを元の状態のままにしておくことができます。

もちろん、そのようにstd::stringwithを割り当てる理由はありませんnew。代わりにこれを書くことができます:

class HasNoPtr {
public:
    HasNoPtr(const std::string& s): ps(s), i(0) { }
private:
    std::string ps;
    int i;
};
于 2015-08-28T00:19:31.253 に答える