2010-01-30 4 views
4

я следующий код:Класс инициализации данных по умолчанию

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

+0

Я действительно ценю все ваши ответы, и я благодарю всех вас за это. Но тот факт, что значения нежелательных сообщений отображаются только после того, как я включаю публичный встроенный элемент данных, оставляет мне мало интересного об этом. Я также проверю это на Dev-CPP и обновляю этот пост, как только я закончу. – mukeshkumar

ответ

2

Нет. Вы просто получаете «повезло». Фундаментальные типы остаются неинициализированными, поэтому ваши 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 будет инициализирован для значимых значений.

+1

Для пользовательских типов вызывается конструктор по умолчанию.Исходя из этого, почему исходные типы не должны быть инициализированы по умолчанию? Любая конкретная причина? – mukeshkumar

+0

C++ не был создан в вакууме, но был разработан как расширение C. Поэтому он не инициализирует фундаментальные типы. (Помните, что класс - это просто структура.) –

+0

@hype: Они не по историческим причинам, как указывает Джон. Я не знаю точной причины, но, вероятно, это было связано со скоростью. В «классическом» C все переменные были объявлены в верхней части функции. Итак, теперь представьте, что мы оставили функцию на полпути: мы бы потратили время на инициализацию переменных. Составители в настоящее время не будут тратить время на эти вещи, будучи намного лучше, но это было тогда, и это застряло. Я лично нахожу это раздражающим, но так оно и есть. – GManNickG

7

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

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

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

В отличие от Java или C#, где память, выделенной для вновь создаваемых объектов всегда устанавливается в ноль, это не happends в C++. Существует несколько правил, которые описывают, когда инициализация объекта гарантирована, и когда это не так.

Рассмотрим folowing пример:

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://stackoverflow.com/a/620402/3073460

+0

Вызывающий конструктор не инициализирует память до 0: Base ob(); По-прежнему требуется, чтобы память была явно инициализирована внутри конструктора класса. –

Смежные вопросы