Совпадение имён глобальных переменных советника и локальных переменных во включаемом файле

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

Есть какой-нибудь способ разграничить области видимости так, чтобы советник видел и мог вызывать функции из включаемого файла, зато функции включаемого файла не видели глобальных переменных советника? А то надоело выдумывать названия для глобальных переменных так, чтобы они точно не совпали с именем локальной переменной в какой-нибудь из функций.
 
Oleg Remizov:
Некоторые универсальные функции, которые используются в каждом или почти каждом советнике я выношу в include-файлы, которые подключаю к каждому советнику. Часто возникает потребность объявить на глобальном уровне советника переменные, имена которых задействованы в функциях подключаемого файла, причём сразу во многих. 

Есть какой-нибудь способ разграничить области видимости так, чтобы советник видел и мог вызывать функции из включаемого файла, зато функции включаемого файла не видели глобальных переменных советника? А то надоело выдумывать названия для глобальных переменных так, чтобы они точно не совпали с именем локальной переменной в какой-нибудь из функций.

class MyClass

private

https://www.mql5.com/ru/docs/basis/types/classes

Документация по MQL5: Основы языка / Типы данных / Структуры, классы и интерфейсы
Документация по MQL5: Основы языка / Типы данных / Структуры, классы и интерфейсы
  • www.mql5.com
Структуры, классы и интерфейсы - Типы данных - Основы языка - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 

Oleg Remizov:

...

А то надоело выдумывать названия для глобальных переменных так, чтобы они точно не совпали с именем локальной переменной в какой-нибудь из функций.

Используйте префикс в имени. Например:

 
Vitaly Muzichenko:

class MyClass

private

https://www.mql5.com/ru/docs/basis/types/classes

То есть во включаемом файле создать класс и все функции сделать его приватными методами? Я просто стараюсь всегда без классов обходиться, так как работать с ними не умею.

 
Malik Arykov:

Используйте префикс в имени. Например:

На данный момент так и делаю, но всё равно иногда сталкиваюсь с тем, что где-то я так уже называл переменные.

 
Посмотрите в сторону extern переменных. Не путать с input.
Как по мне, то тут лучше подойдёт ООП. 
 
Oleg Remizov:
Часто возникает потребность объявить на глобальном уровне советника переменные, имена которых задействованы в функциях подключаемого файла, причём сразу во многих.

Олег, почему возникает такая необходимость?

Изолируйте функции:

Внутри функции используйте переменные с префиксом, можно одинаковым для всех функций. Зона видимости таких переменных в пределах этих функции. Любые глобальные переменные передавайте в функции исключительно через аргументы. И в глобальных переменных не используйте этот префикс. В итоге функции полностью изолированы от внешней среды, и общаются с этой средой только аргументами или возвращаемым значением.

double price1;
double price2;

void OnTick()
   {
   double price3=Add(price1,price2);
   Replace(price1,price2);
   }

double Add(double ePrice1, double ePrice2)
   {
   return(ePrice1+ePrice2);
   }

void Replace(double &ePrice1, double &ePrice2)
   {
   double ePrice3=ePrice1;
   ePrice1=ePrice2;
   ePrice2=ePrice3;
   }
 
Oleg Remizov:

Я просто стараюсь всегда без классов обходиться, так как работать с ними не умею.

А вот это вы зря. Но все поправимо. Посмотрите как это делают другие. Например

Вот класс со статическими функциями, которые можно вызывать не создавая объектов. Все функции лежат по полочкам. Один раз отладил - пользуешься везде

// -----------------------------------------------------------------------------
// Файловые функции
// -----------------------------------------------------------------------------
class UFile {
public:
    static bool IsDirectory(string path);
    static string Parent(string path);
    static string FileName(string path);
    static string FileNameWithoutExt(string path);
    static int FindFiles(string path, CArrayString *paths);
    static string LoadText(string path, CArrayString *lines);
    static bool SaveText(string text, string path, bool reset);
    static bool SaveText(CArrayString *lines, string path);
};

А это "динамический" класс

// -----------------------------------------------------------------------------
// Бар
// -----------------------------------------------------------------------------
class Bar : public CObject {
public:
    datetime    Time; // время окрытия
    double      Open; // цена открытия
    double      High; // макс.цена за период
    double      Low; // мин.цена за период
    double      Close; // цена закрытия
    double      Ma8; // дин.уровень ЕМА 8
    double      Ma21; // дин.уровень ЕМА 21
    double      TopBody; // цена верхней части тела
    double      BottomBody; // цена нижней части тела
    NBodyBar    Body; // вид бара (белый/черный/дожи)
    Bar(){};
    Bar(datetime time, double open, double high, double low, double close, double ma21, double ma8);
    string ToCsv(char delimiter);
};

Обратите внимание все члены в общем доступе, как в структуре. В данном случае это более удобно, чем локальные переменные класса и методы доступа. Основные принципы:

  • Не допускай дублей кода. Если видишь несколько одинаковых кусков кода в разных местах, то смело "заворачивай" этот кусок в функцию.
  • Будь(программируй) проще и все будет ОК
 
Oleg Remizov:

То есть во включаемом файле создать класс и все функции сделать его приватными методами? Я просто стараюсь всегда без классов обходиться, так как работать с ними не умею.

Ну если без классов, тогда можно использовать namespace:

https://www.mql5.com/ru/docs/basis/namespace

Документация по MQL5: Основы языка / Пространства имен
Документация по MQL5: Основы языка / Пространства имен
  • www.mql5.com
Пространства имен - Основы языка - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Oleg Remizov:
Некоторые универсальные функции, которые используются в каждом или почти каждом советнике я выношу в include-файлы, которые подключаю к каждому советнику. Часто возникает потребность объявить на глобальном уровне советника переменные, имена которых задействованы в функциях подключаемого файла, причём сразу во многих. 

Есть какой-нибудь способ разграничить области видимости так, чтобы советник видел и мог вызывать функции из включаемого файла, зато функции включаемого файла не видели глобальных переменных советника? А то надоело выдумывать названия для глобальных переменных так, чтобы они точно не совпали с именем локальной переменной в какой-нибудь из функций.

Если локальная переменная имеет такое же имя как глобальная, то глобальная переменная внутри функции будет скрыта.

Компилятор даже выдаёт такое предупреждение.

Но при желании к ней всё равно можно получить доступ.

int x = 5;

void OnStart()
{
   int x = 10;
   
   Print( "x = ", x );  // Печатаем локальную переменную.
   
   Print( "x = ", ::x );  // Печатаем глобальную переменную.
}
Причина обращения: