首页 > 解决方案 > 为什么使用指针而不是直接实例化对象时不采用类成员的默认值?

问题描述

在以下代码中:

#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,就像上面一样。他们不应该打印相同的吗?为什么使用指针而不是直接实例化对象时不采用类成员的默认值?

标签: c++oopinitialization

解决方案


他们不应该打印相同的吗?

不,是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(或更高版本)模式编译您的代码。


推荐阅读