-
头一次碰到g++出现了一个很奇怪的警告,输出信息大概是 : In instantiation of …required from here …warning
-
改来改去改不掉,最终发现是因为构造函数初始化列表没有按照类内声明变量的顺序来写,比如
class A {
public:
A(int a, char b) :m_b(b), m_a(a) { } // warning
private:
int m_a;
char m_b;
}
// 改成下面这样就没警告了
class A {
public:
A(int a, char b) : m_a(a), m_b(b) { } // no warning
private:
int m_a;
char m_b;
}
- 看起来无厘头的警告其实是有道理的。经查证,初始化列表执行的顺序与书写初始化列表时的顺序无关,和在类内声明变量的顺序一样。产生警告就是告诉我们,这里可能与我们书写的顺序不一样,在一个成员变量的初始化与另一个成员变量有关时,可能造成BUG。比如:
class String {
public:
String(const char * str) : m_str(str), m_len(std::strlen(m_str)) { }
private:
uint64_t m_len;
char m_str;
}
- 上面的程序可能出现不符合预期的结果, 甚至Crash, 因为虽然m_len好像在m_str构造后构造, 但是实际上是在其前构造, 相当于对一个野指针调用strlen, 后果不用多说。
- 养成习惯 :初始化列表按顺序书写,初始化列表内不要利用一个成员变量去构造另一个