2012-08-01 106 views
1

我有一個class在C++中調用Tracer。在我Tracer.h文件我有:const void *對象初始化問題C++

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:80Tracer.hm_theObject的聲明Tracer.cpp:27m_theObject(theObject系列。 在我的彙編級別,警告被視爲錯誤。爲什麼編譯器會抱怨const void *指針的初始化?

+0

在初始化程序列表中交換'm_lineNum(line)'和'm_theObject(theObject)'。 – Joe 2012-08-01 12:47:58

回答

3

有時編譯器會在成員在成員初始化列表中以不同於它們在頭中聲明的順序進行初始化時發出警告。我見過g ++之前做過。如果您對初始化列表重新排序,以使它與成員出現在頭文件中的順序相同,則應該看到此警告消失。

4

這不是整個警告。它實際上是警告m_lineNumm_theObject以錯誤的順序進行初始化(見Member fields, order of construction):

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. 
0

的這裏的問題是,按照C++標準,成員變量總是ALWAYS)在聲明的順序進行初始化,REG無論您在構造函數中給出的順序如何。

編譯器很好地警告你關於你的失配,因爲可能你引入了無意的依賴鏈。


例子:

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'; 
} 

人們可能再次期待ou輸入123,因爲它看起來像_3是在該構造函數中首先啓動的。但事實並非如此:

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

結果是完全不可預知的,多次運行給出不同的結果,甚至沒有重新編譯。編譯器是爲了防止這樣的事故。