c++ - simple - la herencia es un modo de
¿Puedo lanzar una clase derivada a una clase base privada, usando un modelo de estilo C? (3)
¿Puedo hacer esto?
class A { ... };
class B : private A
{
const A &foo() const
{
return *((const A *)this);
}
};
¿Puedo tomar una subclase que herede de forma privada de una clase base y convertirla en una versión pública de su clase base? ¿Puedo hacer esto sin tener métodos virtuales?
Supongo que sí, pero quería asegurarme de que sea seguro / portátil.
Base en el título de su pregunta, la respuesta depende. Pero para su caso en su código fuente, la respuesta es sí.
Hay dos factores que impactarán la respuesta:
Si está utilizando el estilo C cast, será sí, porque cast emitirá una conversión re-interpert si no hay conversión disponible. Puede convertir cualquier tipo de puntero al tipo de puntero de destino. Pero si hay MI, el resultado puede ser incorrecto para la mayoría de las implementaciones en lenguaje C ++.
Si realiza el reparto (sin el reparto de estilo C) dentro de la función memeber, la respuesta será sí, porque la clase base es accesible dentro de la función miembro. Si la expresión está en la ubicación donde la clase base es inaccesible, obtendrá un error de compilación.
Hay más detalles sobre la conversión estándar en el estándar C ++.
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.
Edición 2: haga la respuesta más detallada.
Sí puede: §5.4 / 7 de la norma:
... las siguientes operaciones static_cast y reinterpret_cast (opcionalmente seguidas por una operación const_cast) se pueden realizar usando la notación de conversión de tipo explícita, incluso si el tipo de clase base no es accesible:
un puntero a un objeto de tipo de clase derivada o un lvalor de tipo de clase derivada puede convertirse explícitamente en un puntero o referencia a un tipo de clase base no ambigua, respectivamente;
Pero trate de no derrotar el propósito de la herencia privada.
Sí, eso está explícitamente permitido. Alexandrescu utiliza esto ampliamente en Modern C ++ Design para su enfoque de diseño basado en políticas:
template <typename Policy>
class foo : Policy
{
public:
void do_something()
{
Policy & p = *this;
p.do_something();
}
};
Entonces, si bien los casos de uso pueden ser limitados, hay algunos por ahí.