c++ - 为什么使用指针而不是直接实例化对象时不采用类成员的默认值?
问题描述
在以下代码中:
#include<iostream>
using namespace std;
class Father
{
public:
int a=11;
void f(){ cout<<"f called"<<endl;}
};
int main(){
Father *obj;
cout <<obj->a<<endl; //I get a garbage value and the compiler issues a warning: 'obj' is used uninitialized in this function
Father f;
cout <<f.a<<endl; // it prints 11
return 1;
}
cout <<obj->a<<endl;
正在打印垃圾值而不是默认值 11,就像上面一样。他们不应该打印相同的吗?为什么使用指针而不是直接实例化对象时不采用类成员的默认值?
解决方案
他们不应该打印相同的吗?
不,是UB。
给定Father *obj;
,用不确定的值obj
默认初始化,
具有自动和动态存储持续时间的非类变量的默认初始化会产生具有不确定值的对象
这意味着obj
不指向任何有效对象并且对其取消引用会导致未定义的行为,一切皆有可能。你需要让它指向一个有效的对象,例如
Father f;
Father *obj = &f;
cout <<obj->a<<endl;
或者
Father *obj = new Father;
cout <<obj->a<<endl;
delete obj;
Father f;
也执行默认初始化。作为类类型,f.a
用 value 初始化11
。
如果 T 是
non-POD (until C++11)
类类型,则考虑构造函数并针对空参数列表进行重载决策。调用选择的构造函数(默认构造函数之一)为新对象提供初始值;
顺便说一句: C++11 支持默认成员初始化程序(如您int a=11;
在 classFather
中编写的),请尝试使用 C++11(或更高版本)模式编译您的代码。
推荐阅读
- google-chrome - 为什么这在谷歌浏览器开发工具的范围选项卡中有一个未定义的值?我期待这个:窗口
- c# - 如何在升 C 中四舍五入十进制数?
- ios - 在实际提交应用程序以供启动之前,如何找到我的应用程序的 iOS App Store 下载 url?
- java - 根据成员变量匹配 2 个对象的 ArrayList
- python - 按小时计算json数据的平均值
- intellij-idea - 当有 x=y 之类的代码时,IntelliJ IDE 热键或快捷方式将 x 与 y 交换
- git - 最后如何从 git index 中删除提交?
- c# - 如何在我的 Angular 应用程序中使用从 .net core API 上传的文件?
- css - 为什么 ::before 伪元素在 flexbox 中占用空间?
- android - 如何修复错误:无法解决:com.google.sceneform.ux:sceneform-ux:1.6.0?