Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 我可以安全地强制转换到同级类来包装受保护的函数吗?_C++ - Fatal编程技术网

C++ 我可以安全地强制转换到同级类来包装受保护的函数吗?

C++ 我可以安全地强制转换到同级类来包装受保护的函数吗?,c++,C++,我在namespace Util中有许多自由函数,它们按照适当封装的精神在类a上运行。类A是一个抽象接口,因此util函数将接收专门的派生变量,例如B。一些自由函数需要访问我不想公开的类A中的私有方法。这主要是由于在一个更大的组件层次结构中所扮演的角色,使得在一个很难改变的领域中的糟糕设计造成的。解决方案是将A子类化为Aimpl,并编写包装函数,如: class A { //Is abstract polymorphic interface public: virtual void Some

我在namespace Util中有许多自由函数,它们按照适当封装的精神在类a上运行。类A是一个抽象接口,因此util函数将接收专门的派生变量,例如B。一些自由函数需要访问我不想公开的类A中的私有方法。这主要是由于在一个更大的组件层次结构中所扮演的角色,使得在一个很难改变的领域中的糟糕设计造成的。解决方案是将A子类化为Aimpl,并编写包装函数,如:

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
,则您知道它不是“可浇铸的”(因此,在本例中,它是A
B
)。据我所知,没有必要捕捉异常。但是
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);
};