使用此技巧从外部访问受保护的成员,但这有效吗

Accessing protected members from outside with this trick, but is this valid?

本文关键字:成员 有效 受保护 访问 从外部      更新时间:2023-10-16

如果我有以下类:

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;

我理解为什么这样做有效,但会有什么不好的后果吗?编译器不介意,并没有任何运行时检查。

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

从技术上讲,这是未定义的行为。因此,它可能会工作,但不是必须的。

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

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

为了保护您的代码,您必须使用dynamic_cast来检查下变频是否有效。

不建议使用reinterpret_cast进行下铸。使用static_castdynamic_cast

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