我使用以下代码访问对象的受保护成员。
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();
}
};
我可以假设所提供的代码可以安全使用(理论上和实践中)吗?
答案 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}}。