为什么C ++原始类型没有像其他类型那样初始化?

时间:2014-04-24 08:33:42

标签: c++ constructor primitive raii

我知道,在C ++中,当你写

int i;

在您有效地为其赋值之前,您无法对变量的值进行任何假设。但是,如果你写

int i = int();

然后您可以保证i0。所以我的问题是,它实际上并不是语言行为的一种不完整性吗?我的意思是,如果我已经定义了一个类MyClass并写了

MyClass myInstance;

我可以放心,没有该类参数的默认构造函数将被调用以初始化myInstance(如果没有,编译器将失败),因为这是RAII原理的结果。但是,当涉及到原始类型时,资源获取似乎不再是初始化。那是为什么?

我不认为改变从C继承的这种行为会破坏任何现有的代码(世界上是否有任何代码假设不能对变量的值做出假设?),因此,我想到的主要可能原因是性能,例如在创建基本类型的大数组时;但是,我仍然想知道是否有一些官方的解释。

感谢。

4 个答案:

答案 0 :(得分:7)

没有。这不是不一致。

如果您的班级定义为:

,该怎么办?
struct MyClass
{
    int x;
    float y;
    char *z;
};

那么这一行并不是你认为的那样:

MyClass myInstance; 

假设在函数内部声明了上述内容,它与:

相同
int x; //assuming declared inside a function

在C ++中,类型大致分为3种即。 POD,非POD,聚合 - 它们之间有明显的区别。请阅读它们及其初始化规则(关于它们的主题太多。在此站点上搜索)。另请阅读static initialization and dynamic initialization

答案 1 :(得分:6)

至少最初,真正的原因是C ++想要所有 与C兼容的对象与它们完全相同 在C 中的原因是(现在仍然是)表现; 具有静态生命期的对象的零初始化是免费的 (因为操作系统必须初始化它给出的所有内存 无论如何,出于安全原因);零初始化 否则花费运行时间(表现理由较少 今天比原来强大,因为编译器很多 更好地确定变量将被初始化 之后,在这种情况下抑制零初始化; 但他们仍然存在;特别是在以下情况下:

char buffer[1000];
strcpy( buffer, something );

如果需要零初始化,我不知道 即使它可以在这里跳过它的编译器 没有必要。)

答案 2 :(得分:3)

如果你写

int i;

那么初始化与否取决于上下文。

  • 命名空间范围→零初始化。
  • 本地功能范围→未初始化。
  • 类成员:取决于构造函数,如果有的话。

缺少局部变量的初始化只是为了提高效率。对于在最低级别重复调用的非常简单的函数,这很重要。 C和C ++是用于构建底层事物的语言。

答案 3 :(得分:1)

当您将函数中的局部变量设置为某个值时,每次调用该函数时,都会进行赋值并将值加载到堆栈中。

例如:

void func()
{
    int i = 0; // Every time `func` is called, '0' is loaded into the stack
    ...
}

这是您可能想要避免的,特别是因为C和C ++语言也被指定用于实时系统,其中每个操作都很重要。

顺便说一句,当你声明MyClass myInstance时,你确实可以确保调用默认构造函数,但你可以选择是否要在该构造函数中做任何事情。

因此,C和C ++语言允许您对原始类型变量做出相同的选择。