私人会员职能&实现文件本地的结构和帮助器

时间:2015-06-23 09:47:56

标签: c++

考虑一个带有一组方法的类

class myClass {
  private:
    int someFunc(const SomeClass&);
  public:
    funcA();
    funcB();
    funcC();
}

在实现文件中,我有一个本地结构定义和一些辅助函数在匿名命名空间中使用它

namespace {
  struct Foo { ... };
  int helperFunc(const Foo&){
    SomeClass c;
    // do stuff with Foo and SomeClass to calculate someInteger
    return someInteger;
  }
  Foo makeFoo(){
     Foo foo;
     // configure foo
     return foo;
  }
}

myClass::funcA(){
  Foo foo = makeFoo();
  return helperFunc(foo);
}
myClass::funcB(){
  Foo foo = makeFoo();
  return helperFunc(foo);
}
myClass::funcC(){
  Foo foo = makeFoo();
  return helperFunc(foo)
}

现在,我发现我需要将helperFunc更改为使用someFunc(c),这是myClass的私有方法。

理想情况下,我想

  • Foo本地的定义保留在匿名命名空间
  • 保持someFunc私有
  • helperFunc保留为函数,因为它在类实现中多次使用
  • makeFoohelperFunc分开,因为在某些情况下会单独使用

作为最后的手段,可以将helperFunc转换为预编译器宏,但我认为这不是很优雅,但仍然希望有一些我不知道的技巧来实现我的目标。 / p>

我非常感谢任何建议。

3 个答案:

答案 0 :(得分:4)

您可以将std::function对象传递给helperFunc。可以使用std::bind

从您的私有方法构造此对象
namespace {
  ...
  int helperFunc(const Foo&, std::function<int(const SomeClass&)> func){
    SomeClass c;
    ...
    // Invoke passed-in function
    int funcResult = func(c);
    ...
    return someInteger;
  }
  ...
}

myClass::funcA(){
  Foo foo = makeFoo();
  return helperFunc(foo, std::bind(&myClass::someFunc, this, std::placeholders::_1));
}

答案 1 :(得分:3)

不止一种方法可以做到这一点。就我个人而言:

namespace detail
{
    int myClassSomeFuncAccessor(const SomeClass&);
}

class myClass {
  private:
    int someFunc(const SomeClass&);
  public:
    int funcA();
    int funcB();
    int funcC();

  private:
    friend int detail::myClassSomeFuncAccessor(const SomeClass&);
};

它有利有弊。

优点:

  • 将类及其访问者与实现类分离

  • detail名称空间访问者表示这不属于&#34;官方公众&#34;接口

缺点:

  • 解耦确实是解耦的:任何人都可以通过detail命名空间访问器
  • 访问内部

答案 2 :(得分:3)

我认为现在是使用C ++关键字'friend'的完美场合。简单地让你成为封装器的内在朋友。这是最干净,支持语言的解决方案。 在关于Alex Allain主题的article中,他很好地解释了C ++中的朋友如何不禁忌说

  

有些人认为拥有朋友类的想法违反了封装原则,因为这意味着一个类可以进入另一个类的内部。然而,考虑到这一点的一种方式是,朋友只是表示世界的一个类的整体界面的一部分。就像电梯修理工可以访问不同于电梯骑手的界面一样,某些类或功能需要扩展访问另一个类的内部。此外,使用friend允许类通过隐藏比除了类的朋友之外的任何其他内容可能需要的更多细节来向外界呈现更具限制性的界面。