Инициализация данных класса по умолчанию - PullRequest
5 голосов
/ 30 января 2010

У меня следующий код:

#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'.
Если вы заметили, что я закомментировал 2 утверждения в этой программе.Во-первых, объявление общедоступных данных pub_data, а затем строка внутри основной печати этих общедоступных данных.
Теперь здесь проблема в том, что если я раскомментирую эти две строки, члены данных класса, т.е. i, ch, pub_data, не будутпри инициализации и при печати они отображают нежелательные значения.
Итак, мой вопрос: в чем здесь разница между публичными данными?
Я использую g ++ 3.4.6

Ответы [ 4 ]

8 голосов
/ 30 января 2010

Ни int, ни char автоматически не устанавливаются в 0. Факт, что это произошло, просто удача.

Вам нужно добавить конструктор, который выполняет инициализацию:

Base() : i(0), ch(0) {}
2 голосов
/ 30 января 2010

Отсутствует. Тебе просто "везет". Фундаментальные типы остаются неинициализированными, поэтому ваши i и ch в том виде, в каком они стоят в программе, вполне могут не всегда быть 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 i, ch и (без комментария) pub_data будет правильно инициализирован в значимые значения.

0 голосов
/ 10 декабря 2013

То, что уже получено, является правильным, но чтобы убедиться, что ваши значения инициализируются нулями, вы также можете просто объявить свой объект как

Base ob();  // notice the parentheses here

или

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

Для более подробной информации, проверьте этот проницательный ответ: https://stackoverflow.com/a/620402/3073460

0 голосов
/ 30 января 2010

В отличие от 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. То, что в первом случае ваш код работает, - чистая случайность.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...