Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Никогда бы не подумал, что порядок написания полей в классе важен. Выходит, что и private, public иногда надо делать по несколько раз внутри класса.
А если повнимательнее посмотреть: чем int a2 лучше string a3 ?
int же ничем не не иницизируется по умолчанию
Сделайте, пожалуйста, коротенький ликбез на тему инициализации. Например, что это такое вообще? И какие нюансы могут с этим быть.
Сделайте, пожалуйста, коротенький ликбез на тему инициализации. Например, что это такое вообще? И какие нюансы могут с этим быть.
Ну инициализация - это присвоение переменной некого начального значения, происходящая в её конструкторе. Если мы говорим о конструкторе по умолчанию, то для простых типов там инициализация не производится. Т.е. этот конструктор - просто пустышка. А вот string и указатели инициализируется NULL. И также все статические переменные и переменные глобальной видимости всегда инициализируются нулём, насколько я знаю.
Ну и как выше было уже сказано, конструкторы всех членов класса выполняются в порядке объявления этих членов. А вот от порядка перечисления этих конструкторов в конструкторе самого класса это не зависит. Т.е. например:
A() : a(0), b(0) { }
равносильно
A() : b(0), a(0) { }
Кстати, возможно было бы правильным, если бы в вышеописанной ситуации компилятор выдавал ошибку. Т.е. мы пытаемся присвоить значение какой-то переменной до запуска её конструктора - это явно противоречит логике. Но надо всё взвесить. Может я не учёл каких нюансов.
Уточню вопрос (А куда пропало "ABCDEFGH" ?) следующим примером
{
a3 = NULL;
StringAdd( a3, "ABCDEFGH" );
return StringLen( a3 );
}
class A { public:
A() : a1( f( a3 ) ) {}
int a1;
string a3;
};
void OnStart() { A a; }
Уточню вопрос примером
{
a3 = NULL;
StringAdd( a3, "ABCDEFGH" );
return StringLen( a3 );
}
class A { public:
A() : a1( f( a3 ) ) {}
int a1;
string a3;
};
Ну да, поведение программы тут может быть непредсказуемым.
Я уже тот свой пост удалил, хотел его на новый поменять )
В общем рекомендация разработчикам: сделать так, чтобы в данных случаях выдавалась ошибка компиляции. Т.е. мы пытаемся присвоить значение переменной до запуска её конструктора - это явно противоречит логике. Надо чтоб компилятор не позволял что либо делать с такими переменными, в том числе отправлять их в другие функции. Тогда все проблемы с порядком объявления отпадут: компилятор просто не позволит сделать неправильный порядок.
В данном случае единственно верный порядок должен быть такой:
A() : a1( f( a3 ) ) {}
string a3;
int a1;
};
В общем рекомендация разработчикам: сделать так, чтобы в данных случаях выдавалась ошибка компиляции. Т.е. мы пытаемся присвоить значение переменной до запуска её конструктора - это явно противоречит логике.
Еще один короткий пример приведу, чтобы разработчики обратили внимание на случайную утечку памяти, поскольку проблема именно в этом
class A { public:
A() : a1( f( a3 ) ) {}
int a1;
string a3;
};
void OnStart() { A a; } //2060 bytes of leaked memory
Еще один короткий пример приведу, чтобы разработчики обратили внимание на случайную утечку памяти, поскольку проблема именно в этом
Ну утечка - это уже следствие, и отнюдь не случайна. Ведь причина - обращение к неинициализированному объекту, в котором может содержаться любой мусор. Хорошо хоть access violation нет. Так что обратить внимание нужно именно на факт обращения к такому объекту, что недопустимо.
MQL тип string это структура (где то на форуме про это писалось) и относиться к ее объявлению и инициализации нужно как к объекту структуры, а не простому типу