是否可以在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正确的结构初始化


当前回答

这是可能的,但前提是初始化的结构体是POD(普通旧数据)结构体。它不能包含任何方法、构造函数,甚至默认值。

其他回答

字段标识符实际上是C初始化式语法。在c++中,只需要按正确的顺序给出值,而不需要字段名。不幸的是,这意味着你需要给他们所有(实际上你可以省略后面的零值字段,结果将是相同的):

address temp_address = { 0, 0, "Hamilton", "Ontario", 0 }; 

它不是在c++中实现的。(同样,char* strings?我希望不会)。

通常情况下,如果你有这么多参数,那就是相当严重的代码味道。但是,为什么不简单地对结构进行值初始化,然后为每个成员赋值呢?

正如其他人提到的,这是指定初始化项。

这个特性是c++ 20的一部分

你有

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.

虽然点表示法意味着你输入更多,但你从使用它中得到的好处超过了这个问题,因此我建议你使用它,除非你有一个小的结构,它的结构缺乏变化,在这种情况下,你可以使用一个初始化列表。记住:无论何时与他人合作,编写易于遵循的代码都是至关重要的。

我今天遇到了一个类似的问题,我有一个结构体,我想用测试数据填充,这些数据将作为参数传递给我正在测试的函数。我想有这些结构的一个向量,并正在寻找一个单行方法来初始化每个结构。

我最终在struct中使用了一个构造函数,我相信在对您的问题的一些回答中也建议了这一点。

让构造函数的实参与公共成员变量具有相同的名称可能是不好的做法,这需要使用this指针。如果有更好的方法,有人可以建议编辑。

typedef struct testdatum_s {
    public:
    std::string argument1;
    std::string argument2;
    std::string argument3;
    std::string argument4;
    int count;

    testdatum_s (
        std::string argument1,
        std::string argument2,
        std::string argument3,
        std::string argument4,
        int count)
    {
        this->rotation = argument1;
        this->tstamp = argument2;
        this->auth = argument3;
        this->answer = argument4;
        this->count = count;
    }

} testdatum;

我在我的测试函数中使用它来调用被测试的函数,使用各种参数,像这样:

std::vector<testdatum> testdata;

testdata.push_back(testdatum("val11", "val12", "val13", "val14", 5));
testdata.push_back(testdatum("val21", "val22", "val23", "val24", 1));
testdata.push_back(testdatum("val31", "val32", "val33", "val34", 7));

for (std::vector<testdatum>::iterator i = testdata.begin(); i != testdata.end(); ++i) {
    function_in_test(i->argument1, i->argument2, i->argument3, i->argument4m i->count);
}