C++ 我可以安全地强制转换到同级类来包装受保护的函数吗?
我在namespace Util中有许多自由函数,它们按照适当封装的精神在类a上运行。类A是一个抽象接口,因此util函数将接收专门的派生变量,例如B。一些自由函数需要访问我不想公开的类A中的私有方法。这主要是由于在一个更大的组件层次结构中所扮演的角色,使得在一个很难改变的领域中的糟糕设计造成的。解决方案是将A子类化为Aimpl,并编写包装函数,如:C++ 我可以安全地强制转换到同级类来包装受保护的函数吗?,c++,C++,我在namespace Util中有许多自由函数,它们按照适当封装的精神在类a上运行。类A是一个抽象接口,因此util函数将接收专门的派生变量,例如B。一些自由函数需要访问我不想公开的类A中的私有方法。这主要是由于在一个更大的组件层次结构中所扮演的角色,使得在一个很难改变的领域中的糟糕设计造成的。解决方案是将A子类化为Aimpl,并编写包装函数,如: class A { //Is abstract polymorphic interface public: virtual void Some
class A { //Is abstract polymorphic interface
public:
virtual void SomeFunc() = 0;
protected:
void ProtectedFunc() {SomeOtherFunc();}
private:
void SomeOtherFunc();
};
class B : public A { //Overrides stuff in A and has added variables
public:
virtual void SomeFunc();
};
在我的另一个文件中定义
namespace {
class Aimpl : public A {
public:
void WrapProtectedFunc() {ProtectedFunc();}
};
}
namespace Util {
void ProtectedFunc(A& instance) {
try {
Aimpl& aimpl = static_cast<Aimpl&>(instance);
aimpl.WrapProtectedFunc();
}
catch (std::bad_cast) {}
}
Util::ProtectedFunc的定义放在cpp文件中,实现了目标;所有用户都可以编写Util::ProtectedFunc(实例),而不是instance->ProtectedFunc()。将无法工作。首先,
WrapProtectedFunc
是私有的,所以无论如何都不能调用它。将编译静态\u cast
,但您将获得未定义的行为。这个catch(std::bad_cast){}
是没有意义的,因为static_cast
从不抛出。简单的解决方案:将WrapProtectedFunc
添加为a的公共成员,因为如果您的自由函数需要访问a的内部,那么它们需要访问a的内部。如果a有任何内部,那么术语“抽象多态接口”是不合适的。顺便说一句,您指定的类A既不是抽象的,也不是多态的。您可以使用动态\u cast
,如果结果为NULL
,则您知道它不是“可浇铸的”(因此,在本例中,它是AB
)。据我所知,没有必要捕捉异常。但是dynamic_cast
与多态性几乎相反,所以我会尽量避免使用这个“操作符”…因为我们是在引用上操作的,如果类型不兼容,dynamic_cast可以抛出。但是静态施法不会,正如@pentadecagon所说的那样。我同意避免演员阵容,只是有必要使用这种丑陋的变通方法。这根本不起作用。你是对的,这是一种未定义的行为,尽管它起作用,但不能依赖。就我所知,这一模式没有其他可行的方法,它只是被打破了。我已经更新了我的问题,以反映问题的最终解决方案,从而避免将ProtectedFunc添加到的接口。
namespace Util {
void ProtectedFunc(A& instance);
}
class A { //Is abstract polymorphic interface
public:
virtual void SomeFunc() = 0;
private:
void SomeOtherFunc();
friend void Util::ProtectedFunc(A& instance);
};