我可以指定默认值吗?

时间:2010-04-07 14:16:32

标签: c++ arrays

为什么在创建对象数组时对于用户定义的类型,使用默认构造函数初始化此数组的每个元素,但是当我创建内置类型的数组时不是这样?

第二个问题:是否可以在初始化数组中的元素时指定要使用的默认值?这样的事情(无效):

char* p = new char[size]('\0');

当我使用数组时,本主题中的另一个问题。我想在创建用户定义类型的数组时,该数组的每个元素都将使用默认值进行初始化。这是为什么?

如果内置类型的数组没有使用默认值初始化其元素,为什么他们会为用户定义的类型执行此操作?

有没有办法以某种方式避免/规避这种默认构造?如果我例如创建了一个大小为10000的数组,它会强制10000个默认构造函数调用,初始化我将(稍后)覆盖的数据,这似乎有点浪费。

我认为这种行为应该是一致的,因此要么初始化每种类型的数组,要么都不应该。我认为内置数组的行为更合适。

5 个答案:

答案 0 :(得分:1)

这就是内置类型在C ++中的工作方式。要初始化它们,您必须提供显式初始化程序。如果不这样做,那么该对象将保持未初始化状态。此行为绝不是特定于数组的。独立对象的行为方式完全相同。

这里的一个问题是,当您使用new[]创建数组时,您提供初始化程序(在当前语言版本中)的选项非常有限。实际上,您可以提供的唯一初始化程序是空()

char* p = new char[size](); 
// The array is filled with zeroes

如果是char类型(或任何其他标量类型),()初始值设定项将导致零初始化,这是您尝试做的事情。

当然,如果你想要的默认值不是零,那你就不走运了,这意味着你必须明确地将默认值分配给new[] - ed数组的元素。

对于使用用户定义的默认构造函数禁用类型数组的默认构造函数调用...好吧,没有办法用普通的new[]来实现。但是,您可以通过实现自己的数组构造过程来实现(例如,std::vector就是这样做的)。首先为整个阵列分配原始内存,然后以您认为合适的任何方式逐个手动构建元素。标准库提供了许多专门用于此目的的原语。其中包括std::allocatoruninitialized_copyuninitialized_fill等功能。

答案 1 :(得分:0)

目前(除非您使用的是新的C ++ 0x),C ++将调用不带参数的构造函数,例如: myClass::myClass()。如果要将其初始化为某些内容,请实现这样的构造函数,以初始化变量。 e.g。


class myChar {
    public:
        myChar();

        char myCharVal;
};

myChar::myChar(): myCharVal('\0') {
}

答案 2 :(得分:0)

  

这样的事情(无效):

据我所知,这完全有效。 不完全,但你可以获得零初始化字符数组:

#include <iostream>
#include <cstdlib>

int main(int argc, char* argv[])
{
    //The extra parenthesis on the end call the "default constructor"
    //of char, which initailizes it with zero.
    char * myCharacters = new char[100]();
    for(size_t idx = 0; idx != 100; idx++) {
        if (!myCharacters[idx])
            continue;
        std::cout << "Error at " << idx << std::endl;
        std::system("pause");
    }
    delete [] myCharacters;
    return 0;
}

该程序不产生任何输出。

  

当我使用数组时,本主题中的另一个问题。我想在创建用户定义类型的数组时,知道每个元素的事实。这个数组的初始化将使用默认值进行初始化?

因为没有很好的语法方法来专门化使用new分配的每个元素。您可以通过使用向量来避免此问题,并提前调用reserve()。向量将分配内存,但在push_back进入向量之前,不会调用构造函数。无论如何,你应该使用向量而不是用户管理的数组,因为新的内存处理几乎总是不是异常安全的。

  

我认为这种行为应该是一致的,因此要么初始化每种类型的数组,要么都不应该。我认为内置数组的行为更合适。

如果你能想到一个好的语法,你可以写一个标准的提案 - 不知道你会得到多少。

为什么在创建对象数组时对于用户定义的类型,使用默认构造函数初始化此数组的每个元素,但是当我创建不是这种情况的内置类型的数组时?
当我使用数组时,本主题中的另一个问题。我想在创建用户定义类型的数组时,该数组的每个元素都将使用默认值进行初始化。这是为什么?
如果内置类型的数组没有使用默认值初始化其元素,为什么他们会为用户定义类型执行此操作?
因为用户定义的类型在调用其构造函数之前永远不会有效。即使没有调用构造函数,内置类型也始终有效。

第二个问题:是否可以指定在初始化数组中的元素时使用的默认值?这样的事情(无效):
上面回答了这个问题。

有没有办法以某种方式避免/规避这种默认构造?例如,如果我创建了一个大小为10000的数组,它会强制进行10000个默认构造函数调用,初始化我将(稍后)覆盖的数据,这似乎有点浪费。
是的,你可以使用我上面描述的矢量。

答案 3 :(得分:0)

C ++哲学是 - 不要为你不需要的东西买单。

我认为这种行为非常统一。如果您的UDT没有默认构造函数,则无论如何都不会运行任何内容,并且行为与内置类型(没有默认构造函数)相同。

答案 4 :(得分:0)

  

为什么在创建对象数组时对于用户定义的类型,使用默认构造函数初始化此数组的每个元素,但是当我创建内置类型的数组时不是这样?

但是如果对象的默认构造函数什么都不做,那么它仍然没有初始化。

class X
{
     public:
         char y;
}
X* data = new X[size]; // defaut constructor called. But y is still undefined.
  

第二个问题:是否可以在初始化数组中的元素时指定要使用的默认值? &GT;这样的事情(无效):

是:

char                data1[size]  = { 0 };
std::vector<char>   data2(size,0);
char*               data3 = new char[size];
memset(data3,0,size);
  

有没有办法以某种方式避免/规避这种默认构造?如果我例如创建了一个大小为10000的数组,它会强制10000个默认构造函数调用,初始化我将(稍后)覆盖的数据,这似乎有点浪费。

是。使用std :: vector。

您可以在不调用构造函数的情况下为所需的所有元素保留空间。

std::vector<char>    data4;
data4.reserve(size);