我使用以下代码来访问对象的受保护成员.
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)
我可以假设提供的代码是安全的(理论上和实践中)吗?
从理论上讲,没有.在实践中,也许,只要没有涉及虚拟功能.标准中的相关段落为5.2.9(2):
类型为" cv1 B" 的左值,其中B是类类型,可以转换为类型"引用cv2 D",其中D是从B派生的类,如果从"指针D"到""的有效标准转换指向B的指针"存在,cv2与cv1相同,或者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公开.