Сегодня я узнал очень полезную новую функцию C ++ 11, которая позволяет прямую инициализацию членов данных в объявлении класса:
class file_name
{
public:
file_name(const char *input_file_name);
~file_name();
private:
char *file_name=nullptr; //data_member is initialized to nullptr;
char *Allocator(int buffer_size); //code to dynamically allocate requested
//size block of memory.
};
Можно ли сделать этот шаг дальше с новыми правилами v11 и инициализировать элемент данных с выводом функции-члена:
class file_name
{
public:
file_name(const char *input_file_name);
~file_name();
private:
char *file_name=Allocator(MAX_PATH); //data_member is initialized with a block of
//dynamic memory of sufficient size to hold
//and valid file name.;
char *Allocator(int buffer_size); //code to dynamically allocate requested
//size block of memory.
};
Это вызовет проблемы?
Нестатическая функция-член (обычно) так или иначе зависит от состояния объекта, в котором она вызывается. Если бы это было не так, на самом деле не было бы причины делать ее нестатической функцией-членом. Теперь вы хотите вызвать функцию, которая зависит от состояния вашего объекта. до указанный объект полностью сконструирован, то есть его инварианты, на которые может полагаться функция, еще не обязательно установлены. Таким образом, использование такой функции потенциально опасно, так как, например, функция может обращаться к неинициализированным переменным. Рассмотрим этот пример:
class Fail {
int a = fun() , b;
int fun() {return b;}
};
Вот a
инициализируется раньше b
, но со значением (неопределенным) b
,
Статическая функция-член должна быть в порядке.
Инициализатор скобки или равенства, который вы используете для инициализации члена, определен в стандарте в разделе 9.2. Пункт 4 говорит «Инициализатор фигурной или равной скобки должен появляться только в объявлении члена данных».
Инициализация элементов в процессе строительства описана в разделе 12.6.2.
Точка 10 описывает порядок: 1) наиболее производный базовый класс, 2) инициализатор прямого базового класса, 3) члены не статических данных 4) составной оператор конструктора.
Это означает, что базовый класс (классы вашего класса) всегда инициализируются, когда вызывается ваш член данных brace-or-equal-initializer.
Пункт 13 раздела гласит: «Функции-члены (включая виртуальные функции-члены) могут быть вызваны для строящегося объекта».… «Однако, если эти операции выполняются в ctor-инициализаторе (или в функции, вызываемой напрямую
или косвенно из ctor-initializer) до завершения всех mem-инициализаторов для базовых классов, результат операции не определен. Msgstr «Это последнее исключение не должно произойти в вашем случае.
Так что да, такого рода заявления должны быть действительными.
Редактировать:
В соответствии с 12.6.2 п.8, фигурная скобка или равный инициализатор используется только в том случае, если конструктор объекта не имеет инициализатора mem для члена (то есть инициализатора с синтаксисом «:»)