在C中的C++构造函数初始化列表替代?

问题描述:

在C++中,类构造函数可以使用初始化列表,我被告知这是一个性能特征,它可以通过避免额外分配来提高性能。所以我想知道是否有类似的方法在C中实现相同的功能,这些功能基本上用于初始化C++类构造函数的结构。在C中的C++构造函数初始化列表替代?

我对C++编译器中的特性如何工作有点不清楚,因此有关该主题的任何其他信息也将被赞赏。

+2

我很怀疑声称它是一个性能特征。 – Joe 2013-03-09 17:05:49

+0

如果您想避免不必要的(重复)初始化,您可以使数据为静态。 – teppic 2013-03-09 17:12:18

+0

@Joe - IIRC声称是在LiveLessons的“C++基础知识”中提出的,但可能是错误的,这当然是在我观看的一些视频教程中做出的。 – dtech 2013-03-09 17:14:30

在C++构造函数中,初始化列表允许C++编译器在成员变量的位置就地创建构造函数,而不是使用赋值运算符,复制构造函数或移动构造函数初始化成员变量。有关更多详细信息,请参阅Section 10.6 of the C++ FAQ

在C中,C编译器没有提供这样的自动操作。这意味着程序员直接控制所有初始化,并且不需要特殊语言功能来避免这些额外的操作。

为了更加清楚一点,可以考虑当你使用分配在C初始化++构造会发生什么:

  1. 成员变量先用临时对象构造
  2. 默认构造函数
  3. 构建
  4. 调用赋值或移动赋值运算符以重新初始化临时的成员变量。
  5. 在临时调用析构函数。

虽然有些编译器可以在某些情况下优化此功能,但是您的里程可能会有所不同,并且C++编译器无法在所有情况下优化这些步骤。现在,考虑程序员如何在C中重复这些步骤:

void my_struct_init(struct my_struct* sp) 
{ 
    member_init_default(&sp->the_member); /* default constructor for member */ 

    struct member memb; /* temporary on stack */ 
    member_init_other(&memb, ...params...); /* initialize memb */ 
    member_assign(&sp->the_member,&memb); /* assign member */ 
    member_finalize(&memb);     /* finalize the temporary */ 
} 

很少有C程序员会这样做(没有很好的理由)。相反,他们会自动的代码的优化:

member_init_other(&sp->the_member, ...params...); 

的功能用C++存在,因为编译器做了很多的东西自动为程序员。这通常会让程序员的生活更轻松,但需要初始化列表等功能来帮助编译器生成最佳代码。 C编译器提供了一个更简单的底层机器模型,自动执行更少的操作,因此需要更少的功能(尽管不一定需要更少的工作)来生成类似的最佳代码。

C没有任何相似的特性,但是因为C也没有构造函数,所以没有不必要的赋值的危险。

更大的原则是,将一个特征引入语言通常需要额外的特征来加强原始特征。一个微不足道的例子是线程。如果线程作为一个功能被构建到语言中,那么如何同步它们就成了一个直接的问题。因此同步也是需要的。所以你可以看到没有内置线程或者同步和语言的语言(比如C),但是没有其他语言。在这里,构造函数是线程的,因为同步是列出初始值设定项。

+0

我知道没有这样的功能,我只是问,如果性能优势是适用的,并且可以在C中实现,就像大多数C++功能那样缺少像多态性一样,例如... – dtech 2013-03-09 17:13:01

+0

在C变量中只是空间记忆直到你分配给他们。在C++中,构造变量,并在声明时使用空值(如果适用)。初始化程序允许您确保在分配所需值之前未分配空值。 – Will 2013-03-09 17:18:26

+0

是@威尔是对的,这正是我所说的。 C++中的构造函数是多个赋值的危险可能导致问题的地方。由于C没有构造函数,所以没有危险,所以不需要任何类似的初始化。作业陈述是你拥有和所有你需要的。 – Gene 2013-03-09 17:20:24

C中没有这样的功能。最接近的是designated initializers

你可以写一个单独的函数,并调用它,当你从一个类创建一个对象,然后把它传递给它:

C:

typedef struct { 
     int x; 
}mine; 

void mine_initializer(mine* me) 
{ 
     me->x = 4; //initialization 
} 

int main(void) 
{ 
     mine me; 
     mine_initializer(&me); 
     return 0; 
} 

你也可以这样做,在C++:

struct mine{ 
     int x; 
     void initialize() 
     { 
       x = 4; //initialization 
     } 
}; 



void main(void) 
{ 
     mine me; 
     me.initialize(); 
     printf("%d",me.x); 
} 

这将输出4作为结果。

+0

不是我真正要求的,再加上你使用成员访问'.'上的一个指针...... – dtech 2013-03-09 17:29:14

+0

@ddriver修正了它! oopsie!你想要一个自动初始化器吗? – 2013-03-09 17:29:32