是否可以在c++中初始化结构,如下所示:
struct address {
int street_no;
char *street_name;
char *city;
char *prov;
char *postal_code;
};
address temp_address = { .city = "Hamilton", .prov = "Ontario" };
这里和这里的链接提到,这种样式只能在C中使用。如果是这样,为什么在c++中不能使用呢?是否有任何潜在的技术原因,为什么它不是在c++中实现的,或者使用这种风格是不好的做法。我喜欢使用这种初始化方式,因为我的结构体很大,而且这种样式可以让我清楚地了解分配给哪个成员的值。
请与我分享是否有其他方法可以达到同样的可读性。
在提出这个问题之前,我已参考以下连结:
C/ c++ for AIX
C结构初始化变量
c++中使用标记的静态结构初始化
c++ 11正确的结构初始化
我发现这种方式做全局变量,不需要修改原来的结构定义:
struct address {
int street_no;
char *street_name;
char *city;
char *prov;
char *postal_code;
};
然后声明一个继承自原始结构类型的新类型变量,并使用构造函数初始化字段:
struct temp_address : address { temp_address() {
city = "Hamilton";
prov = "Ontario";
} } temp_address;
虽然没有C风格那么优雅…
对于局部变量,它需要在构造函数的开头添加一个额外的memset(this, 0, sizeof(*this)),所以它显然并不差,@gui13的答案更合适。
(注意,'temp_address'是一个'temp_address'类型的变量,但是这个新类型继承自'address',可以在任何需要'address'的地方使用,所以它是OK的。)
你有
The standard initialization list
address temp_address {
/* street_no */,
/* street_name */,
...
/* postal_code */
};
address temp_address2 = {
/* street_no */,
/* street_name */,
...
/* postal_code */
}
The dot notation
address temp_address;
temp_address.street_no = ...;
temp_address.street_name = ...;
...
temp_address.postal_code = ...;
The designated aggregate initialization, where the initialization list contains that labels of each member of the structure (see documentation) available from C++20 onward.
Treating a struct like a C++ class - in C++ structures are actually special types of classes, where all members are public (unlike a standard C++ class where all members are private if not specified otherwise explicitly) as well as that when using inheritance they default to public:
struct Address {
int street_no;
...
char* postal_code;
Address (int _street_no, ... , char* _postal_code)
: street_no(_street_no),
...
postal_code(_postal_code)
{}
}
...
Address temp_address ( /* street_no */, ..., /* postal_code */);
当涉及到初始化结构的方式时,你应该考虑以下方面:
Portability - different compilers, different degree of C++ standard completeness and different C++ standards altogether do limit your options. If you have to work with let's say a C++11 compiler but want to use the C++20 designated aggregate initialization you are out of luck
Readability - what is more readable: temp_address.city = "Toronto" or temp_address { ..., "Toronto", ... }? Readability of your code is very important. Especially when you have large structures (worse - nested ones), having unlabeled values all over the place is just asking for trouble
Scalability - anything that depends on a specific order is not a good idea. The same goes for lack of labels. You want to move a member up or down the address space of the structure? Good luck with an unlabeled initialization list (hunting down swapped values in structure initialization is a nightmare)... You want to add a new member? Again good luck with anything that depends on a specific order.
虽然点表示法意味着你输入更多,但你从使用它中得到的好处超过了这个问题,因此我建议你使用它,除非你有一个小的结构,它的结构缺乏变化,在这种情况下,你可以使用一个初始化列表。记住:无论何时与他人合作,编写易于遵循的代码都是至关重要的。