MetaEditor build 1471 - страница 3

 
fxsaber:
Никогда бы не подумал, что порядок написания полей в классе важен. Выходит, что и private, public иногда надо делать по несколько раз внутри класса.
Да. Поэтому такое решение в практическом применении - крайне нежелательно, иначе потом разгребать долго придётся, если вдруг перепутал порядок.  Ну либо в комментарии тремя восклицательными знаками отметить, что порядок менять нельзя ни в коем случае!!! )
 
A100:
А если повнимательнее посмотреть: чем int a2 лучше string a3 ?
int же ничем не не иницизируется по умолчанию
 
Alexey Navoykov:
int же ничем не не иницизируется по умолчанию

Сделайте, пожалуйста, коротенький ликбез на тему инициализации. Например, что это такое вообще? И какие нюансы могут с этим быть.

 
fxsaber:

Сделайте, пожалуйста, коротенький ликбез на тему инициализации. Например, что это такое вообще? И какие нюансы могут с этим быть.

Ну инициализация - это присвоение переменной некого начального значения, происходящая в её конструкторе.   Если мы говорим о конструкторе по умолчанию, то для простых типов там инициализация не производится.  Т.е. этот конструктор - просто пустышка.  А вот string и указатели инициализируется NULL.   И также все статические переменные и переменные глобальной видимости всегда инициализируются нулём, насколько я знаю.

Ну и как выше было уже сказано, конструкторы всех членов класса выполняются в порядке объявления этих членов.   А вот от порядка перечисления этих конструкторов в конструкторе самого класса это не зависит.  Т.е. например:

A() : a(0), b(0)  {  }

равносильно

A() : b(0), a(0)  {  }

 
Alexey Navoykov:

Кстати, возможно было бы правильным, если бы в вышеописанной ситуации компилятор выдавал ошибку.  Т.е. мы пытаемся присвоить значение какой-то переменной до запуска её конструктора - это явно противоречит логике.  Но надо всё взвесить. Может я не учёл каких нюансов.

Уточню вопрос (А куда пропало "ABCDEFGH" ?) следующим примером

int f( string& a3 )
{
        a3 = NULL;
        StringAdd( a3, "ABCDEFGH" );
        return StringLen( a3 );
}
class A { public:
        A() : a1( f( a3 ) ) {}
        int a1;
        string a3;
};
void OnStart() { A a; }
Результат дает ответ на вопрос: 1 leaked strings left (утечка памяти)
 
A100:

Уточню вопрос примером

int f( string& a3 )
{
        a3 = NULL;
        StringAdd( a3, "ABCDEFGH" );
        return StringLen( a3 );
}
class A { public:
        A() : a1( f( a3 ) ) {}
        int a1;
        string a3;
};
Результат: 1 leaked strings left

Ну да, поведение программы тут может быть непредсказуемым.

Я уже тот свой пост удалил, хотел его на новый поменять ) 

В общем рекомендация разработчикам:  сделать так, чтобы в данных случаях выдавалась ошибка компиляции.  Т.е. мы пытаемся присвоить значение переменной до запуска её конструктора - это явно противоречит логике.  Надо чтоб компилятор не позволял что либо делать с такими переменными, в том числе отправлять их в другие функции.  Тогда все проблемы с порядком объявления отпадут: компилятор просто не позволит сделать неправильный порядок. 

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

class A { public:
        A() : a1( f( a3 ) ) {}
        string a3;
        int a1;
};
 
Alexey Navoykov:

В общем рекомендация разработчикам:  сделать так, чтобы в данных случаях выдавалась ошибка компиляции.  Т.е. мы пытаемся присвоить значение переменной до запуска её конструктора - это явно противоречит логике.

Еще один короткий пример приведу, чтобы разработчики обратили внимание на случайную утечку памяти, поскольку проблема именно в этом 

int f( string& a3 ) { return StringInit( a3, 1024, 10 ); }
class A { public:
        A() : a1( f( a3 ) ) {}
        int a1;
        string a3;
};
void OnStart() { A a; } //2060 bytes of leaked memory
 
A100:

Еще один короткий пример приведу, чтобы разработчики обратили внимание на случайную утечку памяти, поскольку проблема именно в этом 

Ну утечка - это уже следствие, и отнюдь не случайна.  Ведь причина - обращение к неинициализированному объекту, в котором может содержаться любой мусор. Хорошо хоть access violation нет.  Так что обратить внимание нужно именно на факт обращения к такому объекту, что недопустимо.
 
Alexey Navoykov:
Ну утечка - это уже следствие, и отнюдь не случайна.  Ведь причина - обращение к неинициализированному объекту, в котором может содержаться любой мусор. Хорошо хоть access violation нет.  Так что обратить внимание нужно именно на факт обращения к такому объекту, что недопустимо.
MQL тип string это структура (где то на форуме про это писалось) и относиться к ее объявлению и инициализации нужно как к объекту структуры, а не простому типу
 
coderex:
MQL тип string это структура (где то на форуме про это писалось) и относиться к ее объявлению и инициализации нужно как к объекту структуры, а не простому типу
А что это меняет?  Конструкторы всех переменных выполняются строго в порядке объявления этих переменных (по крайней мере в C++ так), независимо от их типа.  И если конструктор string не запускался, то что в нём может содержаться?
Причина обращения: