Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.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++,考虑一个具有一组方法的类 class myClass { private: int someFunc(const SomeClass&); public: funcA(); funcB(); funcC(); } 在实现文件中,我有一个本地结构定义和一些在匿名命名空间中使用它的帮助函数 namespace { struct Foo { ... }; int helperFunc(const Foo&){ SomeClass

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

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
    private
  • helperFunc
    保留为函数,因为它在类实现中被多次使用
  • makeFoo
    helperFunc
    分开,因为它在某些情况下是单独使用的

作为最后的手段,我们可以将代码> HelPurfc转换成一个预编译器宏,但是我认为这不是很优雅,仍然希望有一些窍门,我不知道实现我的目标。


我非常感谢您的建议。

有多种方法可以做到这一点。我个人认为:

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
    名称空间访问器表示这不是“官方公共”接口的一部分

缺点:

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

您可以将
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));
}
名称空间{
...
int helperFunc(const Foo&,std::function func){
c类;
...
//调用传入函数
int funcResult=func(c);
...
返回一个整数;
}
...
}
myClass::funcA(){
Foo-Foo=makeFoo();
返回helperFunc(foo,std::bind(&myClass::someFunc,this,std::placeholders::\u 1));
}

我认为现在是使用C++关键词“朋友”的最佳时机。只需让您的内部类成为封装器的朋友。这是最干净且语言支持的解决方案。 关于Alex Allain的一个话题,他很好地解释了C++中的朋友不是禁忌说< /P> 有些人认为,拥有好友类的想法违反了封装原则,因为这意味着一个类可以访问另一个类的内部。然而,考虑这一点的一种方式是,friend只是类的整体接口的一部分,它向世界显示。就像电梯维修工可以访问与电梯乘客不同的接口一样,某些类或函数需要扩展访问另一个类的内部。此外,使用friend允许类通过隐藏比除类的朋友以外的任何人都需要的更多的细节,向外部世界提供更严格的接口


helperFunc
需要使用
someFunc
还是只使用它返回的值?也许您可以在
funcA
funcB
funcC
中调用
helperFunc
只需要
someFunc
返回的值,但是
someFunc
将在
helperFunc
中本地实例化的内容作为参数。感谢您提出这一点,我将相应地编辑我的问题。为什么不声明Foo或Foo::helperFunc为myClass类的朋友?在我的理解中,
friend
声明需要发生在
myClass
的定义中。这反过来需要在
myClass
的头中声明参数类型
Foo
,我不想这样做这一点很好,但请注意,您不能将匿名命名空间中的函数声明为友元。所以要走这条路,你需要采取Ami Tavory的方法。如果有人通过
细节
访问内部,他们基本上是在自找麻烦,再往前一步,他们会做
#定义公私
@kw,我同意你的观点,这是一个骗局。尽管如此,这种方法已经非常成熟。gtest文档支持它。Python欣然接受它,我只是指出它不是一个真正的骗局。它只对对自己有危险的小用户子集有危险:)