A partir de la discusión de esta pregunta How is access for private variables implemented in C++ under the hood?, planteé una variación: en lugar de acceder a un miembro de datos privados, ¿puede uno llamar a funciones de miembros privados a través de la transmisión y confiar en la compatibilidad de diseño?¿Se puede acceder a las funciones de miembros privados a través de conversión a tipos compatibles con el diseño?
Parte del código (inspirado en la columna de Herb Sutter Uses and Abuses of Access Rights)
#include <iostream>
class X
{
public:
X() : private_(1) { /*...*/ }
private:
int Value() { return private_; }
int private_;
};
// Nasty attempt to simulate the object layout
// (cross your fingers and toes).
//
class BaitAndSwitch
// hopefully has the same data layout as X
{ // so we can pass him off as one
public:
int Value() { return private_; }
private:
int private_;
};
int f(X& x)
{
// evil laughter here
return (reinterpret_cast<BaitAndSwitch&>(x)).Value();
}
int main()
{
X x;
std::cout << f(x) << "\n"; // prints 0, not 1
return 0;
};
Nota: esto funciona (al menos en Ideone)! ¿Hay alguna manera de que el nuevo C++11 Standard proporcione un garantizado o al menos un definido por la implementación forma de eludir el control de acceso confiando en la compatibilidad de diseño y reinterpret_cast/static_cast?
EDIT1: salida de Ideone
Edit2: En la columna de Sutter enumera dos razones por las que el código anterior no está garantizada para trabajar (aunque funciona en la práctica)
un) Los diseños de objetos de X y BaitAndSwitch no tienen la garantía de ser iguales, aunque en la práctica probablemente siempre lo sean.
b) Los resultados de la reinterpret_cast no están definidos, aunque la mayoría de los compiladores permitirán que intenta utilizar la referencia de resultado en la forma el pirateo informático destinada.
¿El nuevo C++ 11 Standard ahora proporciona estas garantías de diseño/reinterpretar_cast?
Puede evitar casi cualquier cosa que desee con 'reinterpret_cast'; ¿Estás preguntando si es posible hacerlo de una manera bien definida? –
@OliCharlesworth Sí, las garantías serían las mejores, la implementación definida como la segunda mejor opción y la UB no tan buena. – TemplateRex
De ninguna manera. El método de clase de nivel de ensamblado es solo una función global con el parámetro "this" oculto, no pertenece a la instancia de clase y no se puede acceder a través de trucos de diseño. –