1

私はC++でclass呼び出されました。Tracer私のTracer.hファイルには次のものがあります。

class Tracer{

public:
    // not useful to the question.
private:
    Logger *m_logger;
    const char *m_who;
    const char *m_fileName;
    const void * m_theObject;
    int m_lineNum;
    int m_log_level;
}

そしてTracer.cpp私は持っています:

Tracer::Tracer(
        Logger *logger,
        const void *theObject,
        const char *who,
        const char *file,
        int line,
        int log_level
        ) :
        m_logger(logger),
        m_who(who),
        m_fileName(file),
        m_lineNum(line),
        m_theObject(theObject),
        m_log_level(log_level)
{
  // more implementation which is not useful to the problem.

問題は、初期化時にm_theObject(theObject)次の警告が表示されることです。

/home/pribeiro/workspace/Tracer.h:80: warning:   'const void* Tracer::m_theObject'
/home/pribeiro/workspace/Tracer.cpp:27: warning:   when initialized here

Tracer.h:80andは行m_theObjectでの宣言です。私のコンパイル レベルでは、警告はエラーのように扱われます。コンパイラがポインタの初期化について不平を言うのはなぜですか?Tracer.hTracer.cpp:27m_theObject(theObjectconst void *

4

3 に答える 3

4

それはすべての警告ではありません。実際には、 と が間違った順序で初期化されていることを警告してm_lineNumm_theObjectます (メンバー フィールド、構築順序を参照)。

Tracer.h:80: warning:   'const void* Tracer::m_theObject' is initialized before 'int Tracer::m_lineNum'
Tracer.cpp:27: warning:   when initialized here

修正は、初期化の順序または定義の順序を入れ替えることです。

Tracer::Tracer(
        Logger *logger,
        const void *theObject,
        const char *who,
        const char *file,
        int line,
        int log_level
        ) :
        m_logger(logger),
        m_who(who),
        m_fileName(file),
        m_theObject(theObject),    // here
        m_lineNum(line),           // and here
        m_log_level(log_level)
{
  // more implementation which is not useful to the problem.
于 2012-08-01T12:48:30.113 に答える
3

ヘッダーで宣言されている順序とは異なる順序でメンバー初期化リストでメンバーが初期化されると、コンパイラが警告を出すことがあります。g++ がこれを行うのを見たことがあります。ヘッダー ファイルに表示されるメンバーと同じ順序になるように初期化リストを並べ替えると、この警告が表示されなくなります。

于 2012-08-01T12:47:26.913 に答える
0

ここでの問題は、C++ 標準に従って、コンストラクターで指定した順序に関係なく、メンバー変数が常に( ALWAYS ) 宣言の順序で初期化されることです。

コンパイラは、意図しない依存関係チェーンを導入する可能性があるため、不適合について適切に警告します。


例:

struct Foo {
    int _1, _2, _3;

    Foo() : _3(_2+_1),  // Third initialization
            _2(_1+_1),  // Second initialization
            _1(1)       // First initialization
    {}
};

#include <iostream>
int main () {
    Foo f;
    std::cout << f._1 << f._2 << f._3 << '\n';
}

出力:

123

しかし、メンバー初期化子の順序により、メンテナーはもっとうまくやれると思うかもしれません:

struct Foo {
    int _1, _2, _3;

    Foo() : _3(3),
            _2(_3-1),
            _1(_2-1)
    {}
};

#include <iostream>
int main () {
    Foo f;
    std::cout << f._1 << f._2 << f._3 << '\n';
}

そのコンストラクターで最初に初期化123されるように見えるように、出力が再び期待されるかもしれません。_3しかし、それは真実ではありません:

./teh_program
13451434436167553
./teh_program
134514344118742913
./teh_program
13451434495068033

結果はまったく予測できず、複数回実行すると、再コンパイルしなくても異なる結果が得られます。そして、コンパイラはこのような事故を防ぐためのものです。

于 2012-08-01T12:57:20.423 に答える