最新消息:

C++为什么要设计在类声明中初始化成员变量?用途是什么?

C++头文件 CPPKU 49浏览 0评论

C++中可以像下面这样,直接在类的声明中对成员变量进行初始化赋值:

class X { int a = 5; }

为什么要这么做?在什么场合下用到这一特性?在构造函数中可以实现相同的效果,为什么不直接在构造函数里初始化?

在C++98标准中,只有整型成员变量,且是用关键字static、const修饰的整型变量,可以在类声明中初始化,而且必须用常量表达式进行初始化。这一限制可以实现编译期初始化,比如:

class X 
{
static const int m1 = 7; // ok
const int m2 = 7; // error: not static
static int m3 = 7; // error: not const
static const int m4 = var; // error: initializer not constant expression
static const string m5 = "odd"; // error: not integral type
// ...
};
int var = 7;

在C++11标准中,允许在类声明中对非静态成员变量进行初始化操作。构造函数可以在运行时对变量进行动态初始化。比如:

class A { public:     int a = 7; };
class A { public:     int a;     A() : a(7) {} };

上面两种写法,效果是一样的。这看起来貌似只是节省了一点打字时间,但其真正的好处体现在有多个构造函数的情况。通常,所有的构造函数对同一变量赋予相同的初始化值:

class A 
{
public:
A(): a(7), b(5), hash_algorithm("MD5"), s("Constructor run") {}
A(int a_val) : a(a_val), b(5), hash_algorithm("MD5"), s("Constructor run") {}
A(D d) : a(7), b(g(d)), hash_algorithm("MD5"), s("Constructor run") {}
int a, b;
private:
// Cryptographic hash to be applied to all A instances
HashingFunction hash_algorithm;
// String indicating state in object lifecycle
std::string s;
};

上面的类中,变量hash_algorithm、s在所有构造函数中分别初始化为同一个值,这在后续维护中,当需要改变其初始值时,必须同时修改多处代码,容易导致遗漏而引起失误。取而代之,我们可以这样做:

class A 
{
public:
A(): a(7), b(5) {}
A(int a_val) : a(a_val), b(5){}
A(D d) : a(7), b(g(d)) {}
int a, b;
private:
// Cryptographic hash to be applied to all A instances
HashingFunction hash_algorithm{"MD5"};
//String indicating state in object lifecycle
std::string s{"Constructor run"};
};

如果一个成员变量同时在类声明中和构造函数中进行了初始化,只有构造函数中的初始化有效(应该是都有效,只是被覆盖了),上面的代码,我们就可以进一步优化为:

class A 
{
public:
A() {}
A(int a_val) : a(a_val) {}
A(D d) : b(g(d)) {}
int a = 7;
int b = 5;
private:
// Cryptographic hash to be applied to all A instances
HashingFunction hash_algorithm{"MD5"};
// String indicating state in object lifecycle
std::string s{"Constructor run"};
};

一般来讲,类的声明在声明文件(.h)中,构造函数在定义文件(.cpp)中,经常出现的情况是,在.h文件中声明了很多的成员变量,在cpp文件中,没有全部进行初始化,导致代码产生BUG。

转载请注明:cppku-C++库 » C++为什么要设计在类声明中初始化成员变量?用途是什么?

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址