在C++中,C风格的初始化器被构造函数所取代,编译时可以确保只执行有效的初始化(即,在初始化后,对象成员是一致的)。
这是一个好习惯,但有时预初始化很方便,就像您的示例一样。面向对象编程通过抽象类或创建型设计模式来解决这个问题。
在我看来,使用这种安全方式会破坏代码的简洁性,有时安全性的权衡可能太昂贵了,因为简单的代码不需要复杂的设计来保持可维护性。
作为另一种替代方案,我建议定义使用lambda表达式的宏来简化初始化过程,使其看起来几乎像C风格:
struct address {
int street_no;
const char *street_name;
const char *city;
const char *prov;
const char *postal_code;
};
#define ADDRESS_OPEN [] { address _={};
#define ADDRESS_CLOSE ; return _; }()
#define ADDRESS(x) ADDRESS_OPEN x ADDRESS_CLOSE
ADDRESS宏扩展为
[] { address _={}; /* definition... */ ; return _; }()
这将创建并调用lambda函数。宏参数也是逗号分隔的,因此您需要将初始化程序放入括号中并像这样调用:
address temp_address = ADDRESS(( _.city = "Hamilton", _.prov = "Ontario" ));
你也可以编写通用的宏初始化器。
#define INIT_OPEN(type) [] { type _={};
#define INIT_CLOSE ; return _; }()
#define INIT(type,x) INIT_OPEN(type) x INIT_CLOSE
但是这个调用略显不美观
address temp_address = INIT(address,( _.city = "Hamilton", _.prov = "Ontario" ));
然而,您可以使用通用的INIT宏轻松定义ADDRESS宏。
#define ADDRESS(x) INIT(address,x)