Ошибки, баги, вопросы - страница 1678

 
Комбинатор:
С помощью этого можно сделать аналог ключевого слова final, прямой запрет дальнейшего наследования.
Да вот как показывает пример выше, нельзя аналог сделать. Нужно final прописывать даже для private-методов.
 
fxsaber:
Да вот как показывает пример выше, нельзя аналог сделать. Нужно final прописывать даже для private-методов.

Странно. для public наследования максимальный доступ должен быть protected а не private.

А в примере функция точно перегружается?

 
Комбинатор:

Странно. для public наследования максимальный доступ должен быть protected а не private.

А в примере функция точно перегружается?

Точно. Сам вот только узнал.

Если в примере сделать

BASE() {Func();} // вместо void Init() {Func();} Вызов Base.Init() - убрать конечно.

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

 

В журнале терминала получаю

2016.09.12 15:49:14.209 Simple_Test (RTS-9.16,M1)       array out of range in 'Simple_Test.mqh' (85,33)

неуклюже лезу в указанное место исходника. Было бы удобно, чтобы из журнала по двойному щелчку на таком сообщении можно было сразу попасть на указанную строчку.

Если кто поддерживает - выскажитесь. 

 
Sergei Vladimirov:

Классика же - интерфейс в базовом классе с переопределением в потомках:

Классика - это когда protected/public-виртуальные методы переопределяются. А вот для private - не так очевидно (в смысле применения). Спасибо, что ответили.
 
fxsaber:
Классика - это когда protected/public-виртуальные методы переопределяются. А вот для private - не так очевидно (в смысле применения). Спасибо, что ответили.

Да, я уже удалил свой пример, не видя вашего ответа, он действительно неудачным был.

Upd. Что-то я сам в азах запутался, пока вам отвечал. Всё правильно было в том примере, зря удалил. Ещё раз он же с примером использования:

class CAnimal
{
private:
   void virtual Speak(){}
};

class CDog : public CAnimal
{
public:
   void Speak(){Print("Гав!");}
};

class CBigDog : public CDog
{
public:
   void Speak(){Print("Громкий гав!");}
};

void OnStart()
{
   CDog oDog;
   oDog.Speak();
   
   CBigDog oBigDog;
   oBigDog.Speak();
   
   CDog* pDog = &oBigDog; 
   pDog.Speak();       // "Громкий гав!", а не "Гав!", как было бы без виртуального метода
}
 
Sergei Vladimirov:

Upd. Что-то я сам в азах запутался, пока вам отвечал. Всё правильно было в том примере, зря удалил. Ещё раз он же с примером использования:

Не хороший пример, т.к. нигде не видно использование интерфейса CAnimal. Да еще двух потомков сделали public. Тему понимаю, так что норм.
 
#property indicator_buffers 1 + 1

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

 
fxsaber:
Не хороший пример, т.к. нигде не видно использование интерфейса CAnimal. Да еще двух потомков сделали public. Тему понимаю, так что норм.

Нормальный пример. Абстрактное животное в принципе какой-то звук издаёт, но неопределённый, поэтому у него метод Speak() вызывать нельзя, его можно вызвать только у животного конкретного вида. Поэтому в базовом классе объявляем закрытый виртуальный метод, а в потомках переопределяем его и открываем.

 
Sergei Vladimirov:

Нормальный пример. Абстрактное животное в принципе какой-то звук издаёт, но неопределённый, поэтому у него метод Speak() вызывать нельзя, его можно вызвать только у животного конкретного вида. Поэтому в базовом классе объявляем закрытый виртуальный метод, а в потомках переопределяем его и открываем.

Хорошо бы в потомках его тоже сделать private. Для лучшего понимания. Не суть, короче.
Причина обращения: