2

初めての寄稿者ですが、過去の投稿を正しくチェックしたと思いますが、うまくいく解決策が見つかりません。私はVisual Studio 2012を使用しています...

基本的に、私がやりたいことは、オブジェクトが所有するログ ファイルに出力をストリーミングすることだけです。これがどの程度正確に達成されるべきかについては問題はありませんが、アーカイブでは何も機能しません。

私が理解しているように、この受け入れられた解決策はうまくいくはずです:

#include <fstream>
// classA.h
class A {
private:
    std::ofstream * _logfile;
public:
    A(void);
    void dosomething(void) const;
}

// classA.cpp
#include classA.h
A::A(void) : _logfile(0) {
    std::ofstream output("logfile.txt",std::ofstream::app);
    _logfile = &output;
}

A::dosomething(void) {
    *_logfile << "Print something" << std::endl;
}

// main.cpp
int main() {
A a = new A();
a->dosomething();
}

これは正常にコンパイルされますが、ハングします。ほとんどの場合、出力が ctor end で消えるためだと思います。この機能を実現するための優れた堅牢な方法は何ですか? その他の StackOverflow の提案を読むと、コンパイラ エラーが発生します...

ありがとう、クリス

4

3 に答える 3

5

コードは、 のコンストラクターで定義されたローカル変数のアドレスを取得しているため、のコンストラクターが完了すると破棄されるため、 が構築された後_logfileダングリング ポインターのような未定義の動作をします。これは未定義の動作であり、ハングの原因と考えられます。AoutputAAoutput_logfiledo_something()

解決するには、std::ofstreamメンバーを使用してAコピー不可にします (ストリームはコピー不可ですが、移動可能であるため):

class A {
private:
    std::ofstream _logfile;
    A(const A&);
    A& operator=(const A&);
public:
    A() : _logfile("logfile.txt",std::ofstream::app) {}
    void dosomething()
    {
        _logfile << "Print something" << std::endl;
    }
};
于 2013-06-24T16:16:25.527 に答える
1

コンストラクターで_logfileは、ローカルofstreamオブジェクトのアドレスに設定しています。コンストラクターが戻ると、このオブジェクトは破棄されます。 _logfileはダングリング ポインターとして残され、dosomething関数内でそれを操作すると、未定義の動作が発生します。_logfileポインターではなく、通常のofstreamオブジェクトとして宣言してみませんか?

于 2013-06-24T16:16:23.527 に答える