c ++ 11 — Нарушающая конфиденциальность — как справляется стандарт C ++?

Рассмотрим приведенный ниже фрагмент кода.

Метод Sayhi () имеет открытый доступ в классе Base.

Sayhi () был переопределен как приватный метод классом Derived.

Таким образом, мы можем вторгаться в чью-то личную жизнь и C ++ не может обнаружить это, потому что все происходит во время выполнения.

Я понимаю, что это «чисто» проверка во время компиляции. Но при использовании некоторой иерархии наследования программисты могут неправильно изменять спецификаторы доступа. Разве стандарт не должен сказать, по крайней мере? какое-то предупреждающее сообщение.

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

Q1. Говорит ли стандарт C ++ о таких аномалиях во время выполнения?

Q2. Я хочу понять, с точки зрения стандарта C ++, почему бы стандарту не предписать разработчикам компилятора диагностику предупреждений?

#include <iostream>

class Base {
public:
virtual void Sayhi() { std::cout<<"hi from Base"<<std::endl; }
};

class Derived : public Base
{
private:
virtual void Sayhi() { std::cout<<"hi from Derived"<<std::endl; }
};int main() {
Base *pb = new Derived;
// private method Derived::Sayhi() invoked.
// May affect the object state!
pb->Sayhi();
return 0;
}

3

Решение

Говорит ли стандарт C ++ о таких аномалиях во время выполнения?

Нет. Контроль доступа осуществляется только во время компиляции и влияет на то, какие имена можно использовать, а не на какие функции можно вызывать.

Так что в вашем примере вы можете получить доступ к имени Base::Sayhi, но нет Derived::Sayhi; и доступ к Base::Sayhi позволяет виртуально вызывать любую функцию, которая переопределяет ее.

Почему стандарт не заставляет разработчиков компиляторов иметь диагностические предупреждения?

Стандарт вообще ничего не говорит о предупреждениях; это просто определяет поведение правильно сформированного кода. Авторы компилятора должны решить, какие предупреждения могут быть полезны; и предупреждение обо всех приватных переопределениях на тот случай, если вы не хотели, чтобы они были переопределены, звучит так, как будто это приведет к множеству ложных срабатываний.

7

Другие решения

Спецификация доступа не может быть ослаблена, ее можно только подтянуть.
Sayhi() является public в базовом классе, поэтому в основном все классы, производные и переопределенные из него, должны ожидать, что метод publicнет вторжения. Спецификация доступа для функций переопределения хорошо определена, так как метод был объявлен public начать с.

2

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

Пока вы считаете это «аномалией» и хотели бы провести диагностику, на самом деле это полезно: вы можете гарантировать, что ваша реализация может использоваться только полиморфно. Производный класс должен иметь только открытый ctor и никаких других открытых функций, все вновь реализованные функции-члены должны быть закрытыми.

0
По вопросам рекламы [email protected]