У меня есть следующий код:
#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
Я думаю, что меня понизят, но я не нахожу ничего плохого в документах 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. То, что в первом случае ваш код работает - это чистая случайность.
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
будет правильно инициализирован до осмысленных значений.
Ни рта, ни CHAN не автоматически инициализируются на 0. То, что это произошло, это просто удача.
Вам нужно добавить конструктор, который выполняет инициализацию:
Base() : i(0), ch(0) {}