为什么C++基元类型不像其他类型那样初始化
Why C++ primitive types are not initialized like the rest of types?
我知道,在C++中,当您编写时
int i;
在有效地为变量赋值之前,不能对变量将保持的值做出任何假设。但是,如果你写
int i = int();
则您可以保证CCD_ 1将是CCD_ 2。所以我的问题是,这难道不是语言行为的不一致吗?我的意思是,如果我定义了一个类MyClass
并编写
MyClass myInstance;
我可以放心,不带类参数的默认构造函数将被调用来初始化myInstance
(如果没有,编译器将失败),因为RAII原理就是这样的。然而,当涉及到基元类型时,资源获取似乎不再是初始化。为什么?
我不认为改变从C继承的这种行为会破坏任何现有的代码(世界上有没有任何代码是基于对变量的值不能做出任何假设的假设工作的?),所以我想到的主要可能原因是性能,例如在创建基元类型的大数组时;但是,我仍然想知道是否有官方对此的解释。
谢谢。
否。这并不是矛盾。
如果你的类被定义为:
struct MyClass
{
int x;
float y;
char *z;
};
那么这条线并没有达到你认为的效果:
MyClass myInstance;
假设上面是在函数内部声明的,它与相同
int x; //assuming declared inside a function
在C++中,类型大致分为3种,即POD、非POD、Aggregate—它们之间有着明显的区别。请阅读它们及其初始化规则(主题太多。请在此网站上搜索)。另请阅读静态初始化和动态初始化。
真正的原因,至少在最初,是C++想要所有与C兼容的对象完全按照它们的行为C中的原因是(现在仍然是)性能;具有静态生存期的对象的零初始化是免费的(因为操作系统必须初始化它提供给出于安全原因,无论如何都要处理);零初始化否则会耗费运行时间。(性能原理较少今天比原来强大,因为编译器更善于确定变量将被初始化以及在这种情况下抑制零初始化;但它们仍然存在;特别是在以下情况下:
char buffer[1000];
strcpy( buffer, something );
如果需要零初始化,我不知道编译器,即使它没有必要。)
如果您编写
int i;
那么初始化与否取决于上下文。
- 命名空间范围&rar;0已初始化
- 本地功能范围&rar;未初始化
- 类成员:取决于构造函数(如果有的话)
缺少对局部变量的初始化只是为了提高效率。对于一个在最低级别重复调用的非常简单的函数,这可能很重要。C和C++是用来构建底层事物的语言。
当您将函数中的局部变量设置为某个值时,每次调用函数时,都会进行赋值并将值加载到堆栈中。
例如:
void func()
{
int i = 0; // Every time `func` is called, '0' is loaded into the stack
...
}
这是您可能想要避免的事情,特别是因为C和C++语言也被指定用于实时系统,在实时系统中,每个操作都很重要。
顺便说一句,当您声明MyClass myInstance
时,您确实可以放心地调用默认构造函数,但您可以选择是否要在该构造函数中执行任何操作。
因此,C和C++语言也允许您对基元类型变量进行相同的选择。
- 我可以使用 decltype() 或其他东西通过指针获取真实类型吗?
- 为什么 c++ 中的 main() 函数不采用除 int 和 void 之外的任何其他返回类型
- 泛型枚举和其他类型的重载模板函数
- 为什么重载运算符可以返回其返回类型以外的其他内容?
- 在其他容器中使用 boost::container::static_vector 时,GCC 编译错误"将'const s'绑定到类型's&'的引用丢弃限定符"
- 将结构时间规范添加到类(似乎没有其他类型的)会导致EXEC_BAD_ACCESS
- 哪些 C++ 数据类型是 Metal 和所有其他 C++ 平台共有的
- 使用其他模板类型参数作为要在函数签名中使用的类型别名声明
- 严格的别名是否会阻止您通过其他类型写入 char 数组?
- 使用字节向量作为其他类型的原始存储是一种好的做法吗
- 只知道运行时的数据类型.如何将数据详细信息隐藏到使用它们的其他类
- C++ 在方程中使用变量;错误:表达式必须具有整数或无作用域枚举类型及其他
- 没有模板变量的模板化类型和其他使用此类的模板化类型
- 从其他类声明类类型变量会给出 C2143 错误(在"*"之前缺少";")
- 针对特殊情况,使用其他状态信息扩展基元类型
- 区分键盘记录器中的密码和其他类型的键盘输入
- C++模板专用化 - 将其他整数类型委托给uint64_t
- 如果类包含基类类型的成员作为第一个元素,后跟其他成员,编译器是否可以优化空基?
- 对于其他类型的void_t,是否有标准的概括
- 如何将模运算符与其他数据类型一起使用