如果我有以下课程:
class Foo
{
protected:
int i;
public:
Foo() : i(42) {}
};
当然,我无法从外部访问受保护的成员,但我可以做这个小技巧:首先我创建一个继承Foo的新类:
class Foo2 : public Foo
{
public:
int GetI() { return i; }
};
现在,每当我有一个Foo实例或指向此类实例的指针时,我都可以通过强制转换访问受保护的成员(因为我不使用任何其他成员):
Foo *f = new Foo();
Foo f2;
std::cout << ((Foo2*)f)->GetI() << std::endl;
std::cout << (reinterpret_cast<Foo2&>(f2)).GetI() << std::endl;
我明白为什么会这样,但是会不会有任何不良后果?编译器不介意,没有任何运行时检查。
答案 0 :(得分:5)
reinterpret_cast<Foo2&>(f2)).GetI()
从技术上讲,这是未定义的行为。所以它可能会有效,但它没有。
答案 1 :(得分:1)
您正在将Foo
对象强制转换为Foo2
对象。
向下转换是从基类到从类派生的类的转换 基类。如果在运行时寻址对象,则向下转换是安全的 实际上是在寻址派生类对象
为了保护您的代码,您必须使用dynamic_cast
检查向下转发是否有效。
建议不要使用reinterpret_cast
进行转码。使用static_cast
或dynamic_cast
。
阅读大量文章,许多人写道不要像玩耍那样使用virtual void GetI()
中有Foo
。