总结C++中的几种结构体初始化的方法

本文介绍了三种结构体初始化方法:通过构造函数、继承模板类及定义时初始化。这三种方法各有优势,可帮助开发者避免使用未初始化的数据导致的问题。

文章地址:http://www.cnblogs.com/vongang/archive/2011/07/30/2122076.html

 

 

结构体能自由组装数据,是一种很常见的数据打包方法。当我们定义一个结构体后,没有初始化就使用,就会使用到垃圾数据,而且这种错误很难发现。对于定义的任何变量,我们最好都先初始化。

 

除了使用memset和ZeroMemory之外,有没有更简单的方法初始化呢?因为有时候每定义一个结构体,就使用一次memset,也会觉得很繁琐。

 

我这里总结三种方法,如果大家有什么好的方法,不妨加上去。

 

1、结构体的构造函数中初始化。

 

2、继承模板类初始化

 

3、定义时初始化

在C++中,结构体与类在使用上已没有本质上的区别了,所以可以使用构造函数来初始化。如下代码所示:

 


 
  1. struct Stu

  2. {

  3. int nNum;

  4. bool bSex;

  5. char szName[20];

  6. char szEmail[100];

 

 

  //构造函数初始化

 


 
  1. Stu()

  2. {

  3. nNum = 0;

  4. bSex = false;

  5. memset(szName,0,sizeof(szName));

  6. memset(szEmail,0,sizeof(szEmail));

  7.  
  8. }

  9. };


 

 

你可能已经发现了,如果结构体中有大量成员,一个个赋值,相当麻烦。那么你可以这样写:


 
  1. struct Stu

  2. {

  3. int nNum;

  4. bool bSex;

  5. char szName[20];

  6. char szEmail[100];

  7.  
  8. //构造函数初始化

  9. Stu()

  10. {

  11. memset(this,0,sizeof(Stu));

  12. //或者是下面的格式

  13. //memset(&nNum,0,sizeof(Stu));

  14.  
  15. }

  16. };


 

如果在结构体中分配了指针,并且指针指向一个堆内存,那么就在析构函数中释放。以上便是在构造函数中初始化。

2、继承模板类初始化

首先定义一个模板基类:


 
  1. template <typename T>

  2. class ZeroStruct

  3. {

  4. public:

  5. ZeroStruct()

  6. {

  7. memset(this,0,sizeof(T));

  8. }

  9. };


 

 

之后定义的结构体都继承于此模板类。 

 


 
  1. struct Stu:ZeroStruct<Stu>

  2. {

  3. int nNum;

  4. bool bSex;

  5. char szName[20];

  6. char szEmail[100];

  7. };


 

 

这样也能实现初始化。

3、定义时初始化。

 


 
  1. struct Stu

  2. {

  3. int nNum;

  4. bool bSex;

  5. char szName[20];

  6. char szEmail[100];

  7. };



//定义时初始化 

Stu stu1 = {0};

 

在有的结构体中,第一个成员表示结构体的大小,那么就可以这样初始化:

 


 
  1. struct Stu

  2. {

  3. int nSize; //结构体大小

  4. int nNum;

  5. bool bSex;

  6. char szName[20];

  7. char szEmail[100];

  8. };

 

 

 Stu stu1 = {sizeof(Stu),0};

 

 

后面的0,可以省略掉,直接写成:Stu stu1 = {sizeof(Stu)};后面自动会用0填充。

总结分析:

以上三种,是据我所知的初始化结构体方法。

前面两种,实际上已经把结构体给类化了,和类的使用差不多。第三种,是纯粹的结构体的写法。

如果用途仅仅限定为结构体,我建议不要加上构造函数,也不要继承于那个模板类,因为这个时候结构体实际上已经是类了。在定义结构体时,将无法使用第三种方式去初始化,当然,此时也不需要初始化了。

看看微软定义的结构体,基本上都没有构造函数和析构函数。因为结构体的意义很明确,它仅仅是对数据的一个包装,如果加上了方法,其意义就变了。

<think>嗯,用户想知道C++结构体初始化列表的使用方法。首先,我得回顾一下C++结构体初始化几种方式。根据之前看到的引用内容,结构体初始化可以通过构造函数、列表初始化等方式进行。用户特别提到初始化列表,可能是指C++11引入的统一初始化语法,或者是构造函数中的成员初始化列表。需要明确两者的区别。 引用1提到C++11允许在定义结构体时给成员赋初始值,还提到了就地初始化和列表初始化。引用2中的例子展示了逐个赋值、构造函数初始化。引用3则通过结构体内部的构造函数来初始化,比如A a(2)。但用户的问题是关于初始化列表,这可能指的是在声明结构体变量时使用花括号{}进行初始化,或者在构造函数中使用初始化列表来初始化成员变量。 首先,需要解释结构体初始化列表在C++中的两种常见情况:一种是使用统一初始化语法在声明时直接初始化,比如Point p{1.0, 2.0, 3.0};另一种是在结构体的构造函数中使用成员初始化列表来初始化成员变量。 可能用户混淆了这两种情况,需要分别说明。比如,在C++11之后,结构体可以使用花括号进行列表初始化,不需要显式定义构造函数。而如果结构体有构造函数,尤其是带参数的构造函数,那么可以使用初始化列表在构造函数定义中初始化成员。 例如,引用3中的例子展示了结构体A有一个构造函数,可以通过A a(2)来初始化。这时候,如果在构造函数中使用成员初始化列表,可能更高效或者必要,特别是当成员是常量或者引用时。 所以,回答应该分两部分:一种是结构体声明时的列表初始化(统一初始化),另一种是构造函数中的成员初始化列表。需要举例说明这两种情况,并引用相关的参考资料来支持说明。 另外,用户可能在实际使用中遇到问题,比如当结构体有多个构造函数时如何选择初始化方式,或者当结构体包含非静态成员时如何使用列表初始化。需要确保示例代码正确,比如使用正确的语法,包括花括号的位置,构造函数参数与成员变量的对应关系等。 可能还需要提到注意事项,比如初始化顺序必须与成员声明顺序一致,否则可能导致问题。或者当使用聚合初始化时,所有成员都必须被初始化,或者允许部分初始化,剩余成员默认初始化等。 总结回答的结构应该是:先介绍C++结构体初始化列表的两种应用场景,分别给出示例代码,并引用相关文献中的例子,最后列出常见问题或注意事项。这样用户能清晰理解不同情况下的使用方法。</think>### C++结构体初始化列表的用法详解 在C++中,结构体初始化列表主要涉及两种场景:**统一初始化语法**(C++11引入)和**构造函数中的成员初始化列表**。以下通过具体示例说明这两种用法。 --- #### 一、统一初始化语法(列表初始化C++11允许通过花括号`{}`直接对结构体成员进行**就地初始化**,无需显式定义构造函数。 **语法规则**: - 初始化顺序必须与成员声明顺序一致 - 允许部分初始化,未显式初始化的成员会被默认初始化 **示例**: ```cpp struct Point { double x = 0.0; // C++11支持成员变量就地初始化[^1] double y; double z; }; int main() { Point p1 = {1.0, 2.0}; // x=1.0, y=2.0, z=0.0(z使用默认值) Point p2{3.0, 4.0, 5.0}; // C++11统一初始化语法 return 0; } ``` --- #### 二、构造函数中的成员初始化列表 若结构体需要更复杂的初始化逻辑(如参数校验、依赖计算),可通过构造函数配合**成员初始化列表**实现。 **语法规则**: - 初始化列表在构造函数参数列表后以`:`开头,用逗号分隔成员初始化表达式 - 初始化顺序由成员声明顺序决定,与初始化列表顺序无关 **示例**: ```cpp struct Student { int id; std::string name; // 构造函数使用初始化列表 Student(int i, const std::string& n) : id(i), name(n) {} // 成员初始化列表[^2] }; int main() { Student s1(101, "Alice"); // 直接调用构造函数 Student s2 = {102, "Bob"}; // 结合列表初始化语法[^3] return 0; } ``` --- #### 三、注意事项 1. **聚合初始化限制**:若结构体包含私有成员或自定义构造函数,则不能使用`{}`进行聚合初始化 2. **默认成员初始化**:C++11允许在结构体内部直接为成员指定默认值,例如:`int score = 60;` 3. **混合初始化**:构造函数初始化列表可与就地初始化结合使用,优先采用初始化列表中的值 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值