2012-08-01 89 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 

结果是完全不可预知的,多次运行给出不同的结果,甚至没有重新编译。编译器是为了防止这样的事故。