1

C++11のムーブ コンストラクターを調べていますが、うまくいきません。実際、この問題は、そのようなコンストラクターを書き始める前にさえあります。抜粋したコードは次のとおりです。

#include <iostream>
#include <string>
#include <sstream>

class Object {
    static std::ostream& log(Object &obj) {
        std::cout << "Object::id = " << obj.mId << "::"; 
        return std::cout;
    }

    unsigned mId = 0;
    std::string *mText = nullptr;

    unsigned nextUniqueId() const {
        static unsigned id = 0;
        return ++id;
    }

    const std::string textInfo() const {
        std::ostringstream oss;
        oss << "mText @ " << &mText;
        if (mText) oss << " = " << *mText;

        return oss.str();
    }

public:
    Object() = delete;
    Object& operator= (const Object&) = delete;

    explicit Object(const std::string& str) : mId(this->nextUniqueId()), mText(new std::string(str)) {
        Object::log(*this) << "constructor::one-argument\n";
    }

    Object(const Object& obj) : mId(this->nextUniqueId()), mText(new std::string(*obj.mText)) {
        Object::log(*this) << "constructor::copy\n";
    }

    virtual ~Object() {
        Object::log(*this) << "destructor::" << this->textInfo() << "\n";
        if (mText) {
            delete mText;
            mText = nullptr;
        }
    }
};

static Object get_object() {
    return Object("random text");
}

int main(int argc, char **argv) {
    Object a("first object");  // OK

    /*
     * Expected behaviour: inside get_object() function new Object is created which is then   copied into
     * variable b. So that new ID should be given.
     */
    Object b = get_object();  // What the hell?! Not what expected! Why?

    std::cout << std::endl;
    return 0;
}

予想される出力は次のようになります。

Object::id = 1::constructor::one-argument    
Object::id = 2::constructor::one-argument
Object::id = 2::destructor::mText @ 0x7fff32c25f70 = random text
Object::id = 3::constructor::copy

Object::id = 3::destructor::mText @ <DIFFERENT THAN IN ID=2> = random text
Object::id = 1::destructor::mText @ 0x7fff32c25f90 = first object

代わりにこれを取得します:

Object::id = 1::constructor::one-argument
Object::id = 2::constructor::one-argument

Object::id = 2::destructor::mText @ 0x7fff32c25f70 = random text
Object::id = 1::destructor::mText @ 0x7fff32c25f90 = first object

b変数がその場で作成されているように見えます(inline多分?)。率直に言って、何が起こっているのかわかりません。誰か説明してもらえますか?

4

3 に答える 3

3

コピー/移動を最適化したコンパイラはすべて...

于 2013-08-12T18:37:32.110 に答える
1

コンパイラは「戻り値の最適化」RVO を適用できるため、コピーが最適化されます。出力メッセージに関連する副作用にもかかわらず、標準ではこれが許可されていることに注意してください。

于 2013-08-12T18:39:40.923 に答える