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

 
A100:

в C++: A::f()

Что такой код выдает?

((A*)&b).f();
 
fxsaber:

Что такой код выдает?

То же самое.

 
Ilya Malev:

То же самое.

что и MQL (при условии его приведения к С++ виду). Но Вы и сами могли проверить это
 
A100:
что и MQL (при условии его приведения к С++ виду). Но Вы и сами могли проверить это

Проверил:


 
Ilya Malev:

Проверил:

По-моему вы что-то не то проверяете.

B*b1=a;

такая запись в MQL означает копирование объекта a - в объект расположенный по указателю b1.  Вообще конечно это не должно было компилироваться.

А чтобы не мешать в кучу объекты и указатели, лучше использовать для указателей префикс p

 
Ilya Malev:

Проверил:

Пожалуйста, не закладывайтесь на это ошибочное поведение.

Здесь 2 проблемы(?):

  1. B *b1=a  - явная ошибка, компилятор воспринимает эту конструкцию, как вызов оператора копирования A::A(const A &)

  2. В первом случае, оптимизатор определил что A::A(const A &) пустая, нет членов - нет доступа по "указателю" (по факту, никакого кода для вызова оператора копирования не осталось, всё было вырезано)
       виртуальная B::f() не перегружается, поэтому вместо виртуального вызова был простой, в B::f() нет адресации к членам, поэтому доступ по "указателю" тоже был вырезан

    Во втором случае, A::f() - попытка виртуального вызова, имеется доступ по "указателю", а объекта a1 нет, т.к. для A *a1=b тоже был вызов пустого конструктора копирования A::A(const A &)
 
Ilyas:

Пожалуйста, не закладывайтесь на это ошибочное поведение.

Здесь 2 проблемы(?):

Я надеюсь, вы пофиксите это ошибочное поведение? (сделать ошибку компиляции)  Потому как можно и случайно допустить такую ошибку, а компилятор никак не реагирует.

 
Alexey Navoykov:

Я надеюсь, вы пофиксите это ошибочное поведение?    Потому как можно и случайно допустить такую ошибку, а компилятор никак не реагирует.

Да, будем исправлять.

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

 
Ilyas:

Пожалуйста, не закладывайтесь на это ошибочное поведение.

Здесь 2 проблемы(?):

  1. B *b1=a  - явная ошибка, компилятор воспринимает эту конструкцию, как вызов оператора копирования A::A(const A &)

  2. В первом случае, оптимизатор определил что A::A(const A &) пустая, нет членов - нет доступа по "указателю" (по факту, никакого кода для вызова оператора копирования не осталось, всё было вырезано)
       виртуальная B::f() не перегружается, поэтому вместо виртуального вызова был простой, в B::f() нет адресации к членам, поэтому доступ по "указателю" тоже был вырезан

    Во втором случае, A::f() - попытка виртуального вызова, имеется доступ по "указателю", а объекта a1 нет, т.к. для A *a1=b тоже был вызов пустого конструктора копирования A::A(const A &)

Спасибо за подробный ответ, однако, логику я немного не понял.

1) Почему компилятор воспринимает конструкцию B* b1=a как вызов оператора копирования А::А(const A&), (а не вызов B::B(const A&), ведь слева от оператора= находится именно класс B)

2) Почему компилятор не выдал предупреждения "конструктор копирования отсутствует"

3) Почему допускается "простой" вызов методов для несуществующих объектов (в то время как попытка непосредственно вызвать B::f() выдает ошибку компиляции "вызов не статического метода")

4) Ну и почему компилятор допускает вообще "простой" вызов виртуального метода? По-моему, виртуальность никак не должна зависеть от наличия или отсутствия данных в объекте

 
Ilya Malev:

1) Почему компилятор воспринимает конструкцию B* b1=a как вызов оператора копирования А::А(const A&), (а не вызов B::B(const A&), ведь слева от оператора= находится именно класс B)

Совершенно верно.  Это ещё одна ошибка MQL, что компилятор свободно разрешает такие вещи:  B b = a;   Это нарушение принципов инкапсуляции.  В С++ такое не компилируется естественно, требуется явное приведение.  И в старых билдах MQL тоже такое нельзя было делать.  

Причина обращения: