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
- 保持
privatesomeFunc
- 将
保留为函数,因为它在类实现中被多次使用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欣然接受它,我只是指出它不是一个真正的骗局。它只对对自己有危险的小用户子集有危险:)