通过传递引用或返回它来初始化结构是更好的风格吗?

Is it better style to initialize a structure by passing a reference or returning it?

假设我有以下内容:

typedef struct {
    int x;
    int y;
    char a;
    char b;
} myStruct;

通过将引用传递给空函数或从函数返回 myStruct 来创建一个带有函数的新 myStruct 更好吗?

void init(myStruct* s){
    //some code
}

int main(){
    myStruct s;
    init(&s);
    return 0;
}

myStruct init(){
    myStruct r;
    //some code
    return r;
}

int main(){
    myStruct s = init();
    return 0;
}

这基本上只是惯例。第一种风格在 C 代码中更常见,第二种风格在 C++ 代码中更常见。

在 C++ 中,他们会说第二个是首选,因为在第一个中,如果你分配了一个结构但忘记调用 init 那么你可能会遇到 "headless object" 的混乱情况正在传递。

在 C++ 中,init 函数通常只是一个构造函数,因此不存在初始化失败的可能性。

在 C++ 中,如果您打开优化,效率不会有任何差异,编译器将执行 "copy elision" 并优化第二个,使其看起来与第一个相似。

就个人而言,我经常对简单数据对象使用聚合初始化:

struct MyStruct {
    int x;
    int y;
    char a;
    char b;
};

int main()
{
    MyStruct s = {10, 20, 'e', 'u'};
}

硬编码默认值如下:

struct MyStruct {
    int x;
    int y;
    char a;
    char b;
};

const MyStruct MyDefault_A = {0, 0, 'a', 'z'};
const MyStruct MyDefault_B = {10, 20, 'e', 'u'};

int main()
{
    MyStruct s = MyDefault_A;
}

这取决于您将什么视为初始状态。对于某些人来说它意味着全零,对于其他人来说它意味着默认状态或有意义的状态。

不同的初始状态定义你有不同的方式来做到这一点。

对于归零结构,你只需要

struct mystruc s = {0};

如果一个结构需要特定的值初始化,它可能看起来像:

struct mystruc s = {1, 2, NULL, 0x1234};

对于non-trival初始化,我个人喜欢这样:

struct mystruc s;
if ( mystruc_init(&s) < 0 ) it_is_fail();

IMO,你的第二种方法 myStruct s = init(); 并不比上述方法更多地强制初始化,程序员可能仍然会 myStruct s; 而没有得到警告,我个人讨厌返回复杂数据类型的局部变量.

如果你的结构初始化不会失败,我个人更喜欢并建议你只按值return它,因为这就是你最终想要的概念上:让函数在其范围之外传递一些值——这正是 return 值的设计目的。

如果你的手指习惯了"this datatype needs initialization"这种成语,那么你就不太可能忘记

MyStruct foo = init_myStruct();

比执行两步 "declare and fill" 过程。更容易阅读,更容易编写。

还必须注意,传递指针的方法不能用于初始化 const 限定的结构, 所以你有基本上别无选择,只能 return 按值计算。