Инициализация значения по умолчанию данных класса

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

#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;
}

Эта программа компилирует и хорошо работает. Вывод показывает, что я инициализируюсь с 0, и ch инициализируется с '\0'.
Если Вы замечаете, что я прокомментировал 2 оператора в этой программе. Сначала объявление общедоступных данных pub_data и второй строка в основной печати этих общедоступных данных.
Теперь здесь проблема, если я некомментирую эти две строки, элементы данных класса, т.е. я, ch, pub_data, кажется, не инициализируюсь и при печати они отображают значения спама.
Таким образом, мой вопрос - то, что данные общественности различия делают здесь?
Я использую g ++ 3.4.6

5
задан mukeshkumar 30 January 2010 в 06:16
поделиться

3 ответа

Я думаю, что меня понизят, но я не нахожу ничего плохого в документах Sphinx и нахожу их намного лучше, чем альтернативу java.

-121--2585293-

Ну, вы можете видеть лямбда как быстрый способ написать метод, который вы хотите использовать только один раз. Например, следующий метод

private int sum5(int n)
{
    return n + 5;
}

эквивалентен лямбде: (n) = > n + 5 . За исключением того, что метод можно вызвать в любом месте класса, а лямбда живет только в объявленной области (Вы также можете хранить лямбды в объектах Action и Func)

Другая вещь, которую лямбда может сделать для вас, это захват области, построение закрытия. Например, если у вас есть что-то подобное:

...methodbody
int acc = 5;
Func<int> addAcc = (n) => n + acc;

Что у вас есть есть функция, которая принимает аргумент, как раньше, но добавленная сумма берется из значения переменной. Лямбда может работать даже после того, как область, в которой было определено, завершена.

Вы можете строить очень аккуратные вещи с лямбдами, но вы должны быть осторожны, потому что иногда вы теряете читаемость с такими трюками, как это.

-121--1261700-

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

0
ответ дан 14 December 2019 в 01:07
поделиться

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

2
ответ дан 14 December 2019 в 01:07
поделиться

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

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

Base() : i(0), ch(0) {}
8
ответ дан 14 December 2019 в 01:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: