Информация об изменениях

Сообщение Re[13]: Книжка по UB от 14.08.2025 8:35

Изменено 14.08.2025 8:38 rg45

Re[13]: Книжка по UB
Здравствуйте, so5team, Вы писали:

S>Ну не совсем:

S>
S>class c1 {
S>  virtual void f() {...};
S>  ...
S>};

S>class c2 : public c1 {
S>  void f() override {...};
S>  ...
S>};

S>class c3 : public c2 {
S>  ... // нет своей версии f().
S>};

S>class c4 : public c3 {
S>public:
S>  c4() { f(); }
S>};
S>


S>В конструкторе c4 мы не делаем прямой вызов c2::f, но именно эта версия и будет вызвана.


Так мы в этом случае и просто f() не сможем вызвать. И оба вызова: f() и c4::f() создадут одинаковые ошибки компиляции. Т.е. даже в таком случае выходит, что эти вызовы неотличимы:

http://coliru.stacked-crooked.com/a/102a88c2bfba9e66

class c1 {
  virtual void f() {};
};

class c2 : public c1 {
  void f() override {};
};

class c3 : public c2 {
  // нет своей версии f().
};

class c4 : public c3 {
public:
  c4() {
      f();      // error: 'virtual void c2::f()' is private within this context
      c4::f();  // error: 'virtual void c2::f()' is private within this context
    }
};

int main() {
}
Re[13]: Книжка по UB
Здравствуйте, so5team, Вы писали:

S>Ну не совсем:

S>
S>class c1 {
S>  virtual void f() {...};
S>  ...
S>};

S>class c2 : public c1 {
S>  void f() override {...};
S>  ...
S>};

S>class c3 : public c2 {
S>  ... // нет своей версии f().
S>};

S>class c4 : public c3 {
S>public:
S>  c4() { f(); }
S>};
S>


S>В конструкторе c4 мы не делаем прямой вызов c2::f, но именно эта версия и будет вызвана.


Так мы в этом случае и просто f() не сможем вызвать. И оба вызова: f() и c4::f() создадут одинаковые ошибки компиляции. Т.е. даже в таком случае выходит, что эти вызовы неотличимы:

http://coliru.stacked-crooked.com/a/102a88c2bfba9e66

class c1 {
  virtual void f() {};
};

class c2 : public c1 {
  void f() override {};
};

class c3 : public c2 {
  // нет своей версии f().
};

class c4 : public c3 {
public:
  c4() {
      f();      // error: 'virtual void c2::f()' is private within this context
      c4::f();  // error: 'virtual void c2::f()' is private within this context
    }
};

int main() {
}


Если добавить спецификацю доступа public в с2 ошибка уйдёт, но, опять же, от обоих вызовов — виртуального и невиртуального получим одинаковый эффект.