4

如果我有以下课程:

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;

我明白为什么会这样,但是会有什么不好的后果吗?编译器不介意,没有任何运行时检查。

4

2 回答 2

5
reinterpret_cast<Foo2&>(f2)).GetI()

从技术上讲,这是未定义的行为。所以它可能会起作用,但不是必须的。

于 2013-03-16T14:46:59.813 回答
1

您正在将对象向下转换为Foo对象Foo2

向下转型是从基类到派生自基类的类的强制转型。只有在运行时寻址的对象实际上是在寻址派生类对象时,向下转换才是安全的

为了保护您的代码,您必须使用dynamic_cast检查向下转换是否有效。

不建议使用reinterpret_cast向下铸造。使用static_castdynamic_cast

阅读大量文章,许多人写道,不要像你一样使用向下转换。一个危险的例子是有一个virtual void GetI()in Foo

于 2013-03-16T15:00:14.887 回答