私有成员函数和结构以及实现文件本地的帮助程序
private member functions & structs and helpers local to the implementation file
考虑一个具有一组方法的类
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
转换为预编译宏,但我认为这不是很优雅,仍然希望有一些我不知道的技巧来实现我的目标。
我非常感谢任何建议。
您可以将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));
}
有不止一种方法可以做到这一点。就我个人而言,我会选择:
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
命名空间访问器访问内部
我认为现在是使用C++关键字"friend"的最佳时机。只需让你的内部类封装的朋友。这是最干净且支持语言的解决方案。在Alex Allain的一篇关于这个话题的文章中,他很好地解释了C++中的朋友说是如何不被禁忌的
有些人认为,拥有友元类的想法违反了封装的原则,因为这意味着一个类可以访问另一个类的内部。然而,考虑这一点的一种方法是,朋友只是一个类的整体界面的一部分,它显示了世界。就像电梯修理工可以访问与电梯操作员不同的接口一样,有些类或函数需要扩展访问另一个类的内部。此外,使用friend允许类通过隐藏比除了类的friend之外的任何东西所需要的更多的细节来向外部世界呈现更严格的接口。
相关文章:
- 在实现文件中使用头文件的通用 lambda
- 在文件上实现迭代器
- C++头文件和类实现出现问题
- 在文件夹迭代上实现 RAII
- 如何使用命令提示符、记事本和 MinGW 使用主文件、头文件和实现文件编译C++程序?
- 用于 Windows 写入临时文件的 mkstemp() 实现
- 类中的数组变量C++导致"was not declared in this scope"实现文件的一个函数中错误,但在构造函数中不会导致错误
- Linux 源代码中普通磁盘文件的"轮询"功能在哪里实现?
- 在 *.cpp 文件中实现的 c++ 函数/方法永远不会内联扩展吗?
- 在实现文件中使用模板参数声明方法
- 在头文件中使用opencv类型来实现未定义的标识符
- 模板实现文件中的匿名命名空间
- 创建单独的实现文件和头文件
- 多文件类实现Cpp
- Reader类实现中的文件读取错误
- MEX文件实现特征库伪内函数崩溃
- openssl rc4 命令行加密和 cpp 文件实现 rc4 之间的区别
- 从其他头文件实现结构
- c++头文件-实现-头文件-实现依赖链
- 内存映射文件实现