4

大規模なプロジェクトから簡略化した次のクラスの例があります。これは、ロガーのスコープを使用してデストラクタでログ エントリを終了するロギング フレームワークに基づいています。

以下のコードは、コンストラクターが暗黙的に削除された関数 ( edit: not true ) であるため、コンパイルされません。これは、std::ostringstreamオブジェクトと関係があるようです。を直接構築できるはずだと思うので、私はそれについて混乱しています。つまり、オブジェクトstd::ostringstreamを直接構築できるはずです。Container

#include <iostream>
#include <sstream>

class Container {
  public:
    std::ostringstream  bufferStream;

  public:
    Container();    // constructor
    ~Container();
};

Container::Container() {
    bufferStream << "Hello ";
}

Container::~Container() {
    std::cout << bufferStream.str() << " [end]" << std::endl;
}

// === Main method ===

int main() {

    Container().bufferStream << "world";   // works fine

    {                                      // causes tons of compiler errors
        Container cont = Container();
        cont.bufferStream << "world!";
    }

    return 0;
}

「works fine」というラベルの付いた行がまさにそれを行っていることに注意してください。「世界」を出力するために直接アクセスできるContainernew を含む匿名オブジェクトをインスタンス化するようです。std::ostringstreamそれContainer自体がメッセージの「Hello」部分を作成し、そのデストラクタがバッファをフラッシュします。

Containerオブジェクトに名前を付けて保存する 2 番目の部分が正しく実行されないのはなぜですか? これが私が得るエラーのサンプルです:

error.cpp: In function ‘int main()’:
error.cpp:28:36: error: use of deleted function ‘Container::Container(const Container&)’
         Container cont = Container();
                                    ^
error.cpp:4:7: note: ‘Container::Container(const Container&)’ is implicitly deleted because the default definition would be ill-formed:
 class Container {
       ^
error.cpp:4:7: error: use of deleted function ‘std::basic_ostringstream<char>::basic_ostringstream(const std::basic_ostringstream<char>&)’
In file included from error.cpp:2:0:
/usr/include/c++/4.8/sstream:387:11: note: ‘std::basic_ostringstream<char>::basic_ostringstream(const std::basic_ostringstream<char>&)’ is implicitly deleted because the default definition would be ill-formed:
     class basic_ostringstream : public basic_ostream<_CharT, _Traits>

... 等々。

4

2 に答える 2

10

これはうまくいきます:

Container cont;
cont.bufferStream << "world!";

でもこれは:

Container cont = Container();

コピー コンストラクターが含まれます。std::ostringstreamはコピー構築可能ではないため、コピー構築可能ではないため、暗黙的に削除されるため、暗黙的に削除されるContainer方法について話しているエラーメッセージが表示されます。Container::Container(const Container&)std::basic_ostringstream<char>::basic_ostringstream(const std::basic_ostringstream<char>&)

このコピーは省略されますが、コピー/移動の省略の要件は、コピー/移動が最初から可能でなければならないことです。

于 2016-04-04T17:40:26.947 に答える
3

Barry が説明したように、ostringstreamはコピー構築可能ではありません。デフォルトのコピーコンストラクターはメンバーごとにコピー構築するため、ここでは生成できません。

ただし、 3 つのルールに従う場合は、コピー コンストラクター (およびコピー代入演算子) を作成し、文字列ストリームに必要なことを行います。それはうまくいくでしょう:

class Container {
    ...
    Container(const Container&); //Copy constructor
};  

Container::Container(const Container &c) {
    bufferStream << c.bufferStream.rdbuf(); 
}

オンラインデモ

于 2016-04-04T17:59:19.730 に答える