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

new*_*bie 2 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();
    }
};
Run Code Online (Sandbox Code Playgroud)

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

Win*_*ute 5

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

类型为" cv1 B" 的左值,其中B是类类型,可以转换为类型"引用cv2 D",其中D是从B派生的类,如果从"指针D"到""的有效标准转换指向B的指针"存在,cv2cv1相同,或者cv资格比cv1更高,并且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;
  }
};
Run Code Online (Sandbox Code Playgroud)

其次,如果您可以从以前Base使用过的新类中派生并使用它Base:

// use this instead of Base everywhere.
class BaseWithAccess {
public:
  void publicfoo() { foo(); }
};
Run Code Online (Sandbox Code Playgroud)

除此之外,我什么都没有.除非你可以改变Base,在这种情况下你可以foo公开.