【发布时间】:2016-08-18 08:48:23
【问题描述】:
我正在开发一个库。我有可以从外部调用的接口类。
我还有一个不应从外部调用的内部引擎。
当我在这里和那里阅读时,我应该隐藏内部引擎类,甚至不填充它的标题。由于我有以下结构:
interface.hpp:
#include "engine.hpp"
class interface{
private:
enigne eng;
};
interface.cpp:
#include "engine.hpp"
//code that uses member variables and functions from eninge
engine.hpp:
class engine{};
要解决填充“engine.hpp”的问题,我应该将代码更改为:
interface.hpp:
class engine;
class interface{
private:
some_smart_pointer<enigne> eng_ptr;
};
interface.cpp:
#include "engine.hpp"
//code that uses member variables and functions from eninge
enigne.hpp:
class engine{};
这解决了问题。但是,从现在开始,engine 是动态分配的。它的所有成员变量都在免费存储中。
我无法理解我必须更改我的设计并在免费商店上分配引擎来解决隐藏实现细节的问题。有没有更好的解决方案?
附:我不是在问为什么这个解决方案有效。我知道如果我将它留在堆栈上,那么知道引擎类的大小是强制性的。我的问题是关于要求可能解决问题的不同设计。
编辑:
interface 和 engine 都有成员变量。
【问题讨论】:
-
提供的任何解决方案只会使您的实施复杂化。如果您担心使用标准分配器的成本(元数据浪费和/或速度),you can always write your own allocator
-
如果
Interface没有成员,只有虚函数,你可以完全隐藏Engine。 -
总有一个 hacky 解决方案:使用单个私有
char data[<size of engine>]和static_cast<engine>(data)。但这是一场维护噩梦,而且真的 hacky。相反,编写自己的分配器可能几乎一样有效,但更清洁。当然,在进行过早优化之前,首先测量 PIMPL 是否真的是性能瓶颈。 -
有一个权衡。如果您更重视隐藏实现而不是简化实现,那么这就是如何做到这一点。如果你更看重一个简单的实现而不是隐藏实现,那么不要这样做。任何告诉您必须始终隐藏实现的人都是错误的。
-
@MartinNyolt 字符缓冲区可能未对齐;您必须确保它与引擎的数据成员正确对齐。