类数据的默认初始化

6

我有以下代码:

#include <iostream>
using namespace std;

class Base
{
private:
    int i;
    char ch;
public:
    void showdata()
    {
        cout<<"Int:"<<i<<endl;
        cout<<"Char:"<<ch<<endl;
    }
    //int pub_data ;
} ;

int main()
{
    Base ob;
    ob.showdata() ;
    //cout<<"Public Data:"<<ob.pub_data<<endl;
    return 0;
}

这个程序编译和运行都很好。输出显示i被初始化为0,ch被初始化为'\0'。
如果你注意到我在这个程序中注释了两条语句。第一是公共数据pub_data的声明,第二是main函数内打印该公共数据的语句。
现在问题是,如果我取消这两行注释,类的数据成员即i、ch、pub_data似乎没有被初始化,当它们被打印时,会显示垃圾值。
所以我的问题是公共数据在这里有什么区别?
我正在使用g++ 3.4.6。

非常感谢您所有的回复,我对此表示感谢。但是,只有在我包含公共内置数据成员后才显示垃圾值这一事实让我有些好奇。我将在Dev-CPP上检查并完成后更新此帖子。 - mukeshkumar
4个回答

8

整型和字符型变量都不会自动初始化为0。现在它们被初始化为0只是一种幸运。

你需要添加一个构造函数来进行初始化:

Base() : i(0), ch(0) {}

2

没有。你只是“走了狗屎运”。基本类型保持未初始化状态,所以在程序中,你的ich可能并不总是0。

恰好添加公共成员“搞砸了”它。要更正你的类,请在构造函数的初始化列表中初始化成员:

class Base
{
private:
    int i;
    char ch;
public:
    Base(void) :
    i(0), ch(0) //, pub_data(0)
    {}

    void showdata()
    {
        cout<<"Int:"<<i<<endl;
        cout<<"Char:"<<ch<<endl;
    }
    //int pub_data ;
} ;

现在,当构造一个名为Base的对象时,ich和(在取消注释时)pub_data将被适当初始化为有意义的值。

1
对于用户定义类型,将调用默认构造函数。按照这个逻辑,为什么基本类型不应该进行默认初始化?有特定的原因吗? - mukeshkumar
C++并非孤立开发,而是被设计为C语言的扩展。因此,它不会初始化基本类型。(请记住,类只是结构体的一种形式。) - Jon Reid
@hype:正如Jon所指出的那样,它们并不是出于历史原因。我不知道确切的原因,但可能与速度有关。在“经典”的C语言中,所有变量都在函数顶部声明。现在想象一下,我们在函数执行到一半时离开了:我们将浪费时间初始化变量。现在的编译器不会浪费时间处理这些事情,因为它们更好了,但当时还是这样的。我个人觉得这很烦人,但事实就是这样。 - GManNickG

0

与Java或C#不同,新创建对象分配的内存总是设置为零,但在C++中并非如此。有几个规则描述了何时保证进行对象初始化以及何时不进行。

考虑以下示例:

class Base
{
private:
    int i;
    char ch;
    std::string str;
public:
    Base()
      : i(0) //built-in fields remains unitialized. We should initialize it manually
      , ch('\0') //another built-in field
      //, str() //this call is redundant due automatic default constructors calls for all user-defined types
    {}
    void showdata()
    {
        cout<<"Int:"<<i<<endl; //valid only after manual initialization
        cout<<"Char:"<<ch<<endl; //valid only after manual initialization
        cout<<"String:"<<str<<endl; //always valid 
    }
    //int pub_data ;
} ;

你应该记住,所有内置字段都应该在类的构造函数中手动初始化。

P.S. 在第一种情况下代码可以正常工作的事实是纯粹的巧合。


-1

前面的回答都是正确的,但为了确保你的值被初始化为零,你也可以简单地将对象声明为

Base ob();  // notice the parentheses here

或者

Base ob{};  // this compiles only on c++11

更多细节请查看这个有见地的答案: https://dev59.com/_3RB5IYBdhLWcg3wcm6d#620402


调用构造函数不会将内存初始化为0: Base ob(); 仍然需要在类的构造函数中显式地初始化内存。 - Kristupas A.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接