在c++中屏蔽尽可能多的类实现
Masking as much as possible of class implementation in C++
我有两个类A
和B
,其中B
使用A
类的对象,如下所示
class A {
private:
int foo_;
A(const int &foo): foo_(foo) {}
}
class B {
// STUFF
inline C operator()(A a)
}
目前,我已经将两者的定义放在.h
文件中,代码编译并正确执行。
我的问题是:我可以屏蔽多少类A
的实现,例如通过将代码行移动到.cpp
文件进行单独编译和链接?我可以屏蔽private
成员和方法的实现(外部用户不能直接访问的所有内容)吗?如何?我应该使用哪些c++关键字?
非常感谢。
屏蔽实现可以通过PIMPL习惯用法或使用简单的多态性来完成,这是一种工厂方法模式。基本上,您创建了一个接口类,如IA
:
/* File: A.h */
#include <memory> /* For std::shared_ptr */
class IA;
/* Change the line below to boost::shared_ptr<> or
* another implementation of a shared-pointer.
* Read more:
* http://en.wikipedia.org/wiki/Smart_pointer#shared_ptr_and_weak_ptr
*/
typedef std::shared_ptr<IA> APtr;
class IA {
public:
static APtr Create(const int foo);
IA(){}
virtual ~IA(){}
virtual void somePublicMethod() = 0;
};
在你的a.p中,你会有它的实现:
/* File: A.cpp */
#include "A.h"
class A : public IA
{
public:
A(const int foo):foo_(foo){}
void somePublicMethod(){/* Your awesome implementation goes here */}
};
APtr IA::Create(const int foo)
{
return APtr(new A(foo));
}
通过这种方式,您只传递接口并只向外部公开公共方法,其内部结构在您的CPP文件中。
优势:
- 对用户完全隐藏实现
缺点:
- 你需要为每个你想隐藏的类创建一个接口
- 用户必须调用工厂方法来创建实例。例如上面示例中的
Create()
。 - 你将总是让你的类实例在堆内存中而不是在堆栈中,也就是说,你的实现实例将总是必须是一个指针。(阅读更多:堆与堆栈内存)
如果您不需要C operator()(A a)
为inline
,您可以转发声明参数A
,如下所示
class A;
然后你可以将它的定义移动到另一个头文件中,并将它包含在使用它的地方。
关于pImpl习语可以隐藏的内容:
- 可以将所有函数定义(包括构造函数和它们的初始化列表)移动到
Impl
类 - 允许您将私有类型、数据成员函数放入Impl类中,除非它们影响类的行为(例如私有构造函数、析构函数和操作符对类的用户有影响)
- 可以将类静态数据成员的定义和初始化移动到实现文件
- 根据Arne的评论,私有基类通常可以移动到实现中(除非你在公共或受保护的数据成员中使用typedef等,根据他的评论,这是丑陋的!)
相关文章:
- 如果没有malloc,链表实现将失败
- 如何在c++中实现处理器调度模拟器
- 如何在c++中使用引用实现类似python的行为
- 实现无开销push_back的最佳方法是什么
- 使用简单类型列表实现的指数编译时间.为什么
- 在c++中检查长方体是否尽可能快地重叠(无迭代)
- 如何在BST的这个简单递归实现中消除警告
- 实现一个在集合上迭代的模板函数
- 我应该实现右值推送功能吗?我应该使用std::move吗
- 如何正确实现和访问运算符的各种自定义枚举器
- C++Union/Struct位域的实现和可移植性
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 在c++中实现LinkedList时,应出现未处理的错误
- 为左值和右值的包装器实现C++范围
- 使用模板进行堆栈实现; "name followed by :: must be a class or namespace"
- 使用GSoap实现ONVIF
- 在用于格式4的arm模拟器中实现功能时的一个问题
- 用于AVX的ln(x)的实现,m256
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 在c++中屏蔽尽可能多的类实现