9

基になるバッファーを所有しているか所有していない、奇妙な文字列型があるとします。

class WeirdString {
private:
    char* buffer;
    size_t length;
    size_t capacity;
    bool owns;

public:
    // Non-owning constructor
    WeirdString(char* buffer, size_t length, size_t capacity)
        : buffer(buffer), length(length), capacity(capacity), owns(false)
    { }

    // Make an owning copy
    WeirdString(WeirdString const& rhs)
        : buffer(new char[rhs.capacity])
        , length(rhs.length)
        , capacity(rhs.capacity)
        , owns(true)
    {
        memcpy(buffer, rhs.buffer, length);
    }

    ~WeirdString() {
        if (owns) delete [] buffer;
    }
};

そのコピーコンストラクターはどこかで標準に違反していますか? 検討:

WeirdString get(); // this returns non-owning string
const auto s = WeirdString(get());

s追加のコピー コンストラクターが省略されたかどうかに応じて、所有または非所有のいずれかになります。これは、C++14 以前では許可されていましたが、省略可能です (C++17 では保証されています)。Schrödinger の所有権モデルは、このコピー コンストラクター自体が未定義の動作であることを示唆しています。

それは...ですか?


より具体的な例は次のとおりです。

struct X {
    int i;

    X(int i)
      : i(i)
    { }

    X(X const& rhs)
      : i(rhs.i + 1)
    { }        ~~~~
};

X getX();
const auto x = X(getX());

どのコピーが省略されるかに応じて、x.iで返されたものよりも 0、1、または 2 増える可能性がありますgetX()。規格はこれについて何か言っていますか?

4

2 に答える 2