考虑一个带有一组方法的类
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
保留为函数,因为它在类实现中多次使用makeFoo
与helperFunc
分开,因为在某些情况下会单独使用作为最后的手段,可以将helperFunc
转换为预编译器宏,但我认为这不是很优雅,但仍然希望有一些我不知道的技巧来实现我的目标。 / p>
我非常感谢任何建议。
答案 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允许类通过隐藏比除了类的朋友之外的任何其他内容可能需要的更多细节来向外界呈现更具限制性的界面。