在c++中,C风格的初始化式被构造函数所取代,构造函数在编译时可以确保只执行有效的初始化(即初始化后对象成员是一致的)。
这是一个很好的实践,但有时预初始化也很方便,就像在您的示例中一样。OOP通过抽象类或创建设计模式解决了这个问题。
在我看来,使用这种安全的方式消除了简单性,有时安全性的权衡可能过于昂贵,因为简单的代码不需要复杂的设计来保持可维护性。
作为另一种解决方案,我建议使用lambdas来定义宏,以简化初始化,使其看起来几乎像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。宏参数也是用逗号分隔的,因此需要将初始化式放在括号中并调用like
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)