在这种情况下,将基类对象强制转换为EMPTY派生类是不安全的

时间:2014-12-10 23:05:40

标签: c++

我使用以下代码访问对象的受保护成员。

class Base {
protected:
    void foo();
};

class PublicBase : public Base {
public:
    static void bar(Base *obj) {
        static_assert(sizeof(PublicBase) == sizeof(Base), "Not today");
        static_cast<PublicBase *>(obj)->foo();
    }
};

我可以假设所提供的代码可以安全使用(理论上和实践中)吗?

1 个答案:

答案 0 :(得分:5)

理论上,没有。在实践中,也许,只要没有涉及虚拟功能。标准中的相关段落为5.2.9(2):

  

类型为“ cv1 B”的左值,其中B是类类型,可以强制转换为“引用 cv2 D”,其中D是类从B派生,如果存在从“指向D的指针”到“指向B的指针”的有效标准转换, cv2 cv1相同的cv资格,或更高的cv资格,B既不是D的虚基类,也不是D的虚基类的基类。结果类型为“ cv2 D”。 (...)如果类型为“ cv1 B”的对象实际上是D类型对象的子对象,则结果引用类型D的封闭对象。否则,结果演员阵容未定义。

强调我的。

编辑:嗯,我在肮脏但合法的黑客攻击中的第一种方法不起作用,这很好,因为我认为存在的漏洞是不应该的漏洞。如果foo具有任何意义,那么我无法合法地*obj protected发送class PublicBase : public Base { public: void bar(Base *obj) { // upcast, perfectly legal. make a working copy into self *static_cast<Base*>(this) = *obj; // work foo(); // copy back *obj = *this; } }; ,这是最好的我可以提供两种解决方法的想法:

首先,如果来回复制(或移动)是可以的

Base

其次,如果您可以从Base派生并使用新类,那么您之前使用// use this instead of Base everywhere. class BaseWithAccess { public: void publicfoo() { foo(); } };

Base
除此之外,我什么都没有。除非您可以更改foo,否则您可以公开{{1}}。

相关问题