Подтвердить что ты не робот

Можно ли применить производный класс к частному базовому классу, используя C-стиль?

Могу ли я это сделать?

class A { ... };

class B : private A
{
    const A &foo() const
    {
        return *((const A *)this);
    }
};

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

Мое предположение - да, но я хотел убедиться, что он безопасен/переносится.

4b9b3361

Ответ 1

Да, вы можете: §5.4/7 стандарта:

... следующие операции static_cast и reinterpret_cast (необязательно, за которым следует операция const_cast), может выполняться с использованием отличная нотация явного преобразования типов, даже если базовый класс тип недоступен:

указатель на объект типа производного класса или значение l производной тип класса может быть явно преобразован в указатель или ссылку на однозначный тип базового класса, соответственно;

Но постарайтесь, чтобы это не побеждало цель частного наследования.

Ответ 2

Да, это явно разрешено. Alexandrescu широко использует это в Modern С++ Design для своего подхода к разработке политики:

template <typename Policy>
class foo : Policy
{
    public:
        void do_something()
        {
            Policy & p = *this;
            p.do_something();
        }
};

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

Ответ 3

Основываясь на заголовке вопроса, зависит от ответа. Но для вашего случая в исходном коде, ответ - да.

Есть два фактора, которые повлияют на answere:

  • Если вы используете C-стиль, это будет да, потому что cast будет вызывать повторный интерперт, если доступность отсутствует. Вы можете указать любой тип указателя на целевой тип указателя. Но если есть MI, результат может быть неправильным для большинства реализаций языка С++.

  • Если вы выполняете актерский состав (без применения стиля C) внутри функции memeber, ответ будет да, так как базовый класс доступен внутри функции-члена. Если выражение находится в том месте, где базовый класс недоступен, вы получите ошибку компиляции.

Более подробно о стандартном конвертировании в стандарте С++

A prvalue of type "pointer to cv D", where D is a class type, can be converted to a prvalue of type "pointer to cv B", where B is a base class (Clause 10) of D. 
If B is an inaccessible (Clause 11) or ambiguous (10.2) base class of D, a program that necessitates this conversion is ill-formed. 
The result of the conversion is a pointer to the base class subobject of the derived class object. The null pointer value is converted to the null pointer value of the destination type.

Изменить 2: сделать более подробным.