在构造函数中初始化数组数据成员

时间:2014-06-02 04:49:37

标签: c++ arrays constructor

我有一个类对象数组,在类对象中我有另一个数组,我需要初始化为全零。代码编译并运行,但我的输出显示为C. 而不是0。

从头文件中:

class Cache {
private:
    int byte[16];
public:
    Cache();
    int getBytes(int);
    ~Cache();
};

来自cpp文件

Cache::Cache()  
{
    byte[16]={0};
}

int Cache::getBytes(int j){
    return byte[j];
}

来自其他cpp文件

for (int i = 0; i < 16; i++) 
{
    for (int j = 0; j < 16; j++)  //visual check of initializes main memory
    {
        cout << cache[i].getBytes(j) << " ";
}
}

这是否设置正确?正如我所提到的,getBytes正在按照预期返回C&#39;而不是&#39; 0。

6 个答案:

答案 0 :(得分:28)

只需在构造函数初始化列表中使用值初始化即可。这是在C ++中这样做的惯用方法。

Cache::Cache() : byte()
{ 
}

请注意,C ++ 11也允许这种语法:

Cache::Cache() : byte{}
{ 
}

如果您想知道为什么这是有效的,请参阅C ++ 11标准(注意这也适用于C ++ 03):

  

C ++11§8.5,p10

     

一个对象,其初始化程序是一组空的括号,即(),应为值初始化

该术语 value-initialized 将我们带到:

  

C ++11§8.5,第7页

     

对T类型的对象进行值初始化意味着:

     
      
  • 如果T是一个(可能是cv限定的)类类型 9 和一个用户提供的构造函数(12.1),那么调用T的默认构造函数(并且初始化生病了-form如果T没有可访问的默认构造函数);

  •   
  • 如果T是一个(可能是cv限定的)非联合类类型而没有用户提供的构造函数,那么该对象是零初始化的,如果T的隐式声明的默认构造函数是非平凡的,那么构造函数被调用。

  •   
  • 如果T是数组类型,则每个元素都是值初始化的;

  •   
  • 否则,该对象为零初始化。

  •   

第三个选项会使每个元素的值初始化失效;第四个适用于我们到达每个元素因为它们(a)没有类类型,因此(1)和(2)消失了,(b)不是数组,所以(3)消失了。这只剩下最后一个,你的元素是零初始化的。

答案 1 :(得分:5)

Cache构造函数中,执行:

byte[16]={0};

您只是设置数组的第16个字节(超出范围,因此此操作具有未定义的行为)。数组对象在C ++中默认初始化,因为您存储int,不执行初始化。

您可以使用std::fill对其进行初始化:

Cache::Cache()  
{
  std::fill(byte, byte+16, 0);
}

或者您可以在阵列上使用常规for循环。

答案 2 :(得分:2)

memset是最简单的解决方案。

Cache::Cache()  
{
  memset(byte, 0, sizeof(byte));
}

答案 3 :(得分:2)

你在很多层面都做错了。您使用的语法不符合您的想法。你现在正在做的是将表的第17个元素初始化为0。

在你的情况下memset可能是最快最简单的。但是,它不适用于复杂类型,因此我会考虑为一般情况编写一个简单的代码段,如:

template<typename T>
inline void zero_init(T array[], size_t elements){
 if( std::is_pod<T>() ) memset(array, 0, sizeof(T)*elements);
 else std::fill(begin(array), begin(array)+elements, 0);
}

这将检查类型是否为POD类型,在此上下文中意味着它可以通过memset进行初始化,并将0用于整个表。如果T不支持它,那么对于每个元素,将调用等效的element = 0。此外,检查可以在编译时进行评估,因此很可能if将被编译掉,并且一个简单的&#34;单行&#34;将在编译时为每种类型创建版本。

您可以通过以下方式致电:

Cache::Cache()  
{
  zero_init(byte, 16);
}

答案 4 :(得分:1)

您的代码存在两个问题:

byte[16]={0};

数组具有基于0的索引,因此在这种情况下,最大索引可以是15,而不是16。你破坏了记忆。

其次,你必须循环遍历所有元素并初始化它们。初始化的方式仅针对一个元素完成。

Cache::Cache()  
{
  for(int i=0;i<16;i++)
   byte[i]=0;
}

答案 5 :(得分:0)

使用{0}的数组初始化仅在声明数组时起作用。

在构造函数中需要一个for循环,将数组元素设置为零。