![]() |
1
12
我可以想到一些不同之处: 使用虚拟基类,可以打破人们期望从行为良好的C++类中得到的一些语义: 我希望(或要求,甚至)类在堆栈上被实例化,如下所示:
否则,我会丢失RAII,并且必须手动开始跟踪分配,这会导致许多头痛和内存泄漏。 我也希望能复制这个类,我可以简单地做这个
当然,除非将复制构造函数标记为private,否则不允许复制,在这种情况下,该行甚至不会编译。 在上面的例子中,我们显然遇到了这样一个问题:您的接口类没有真正有意义的构造函数。但是如果我尝试使用上面的示例这样的代码,我也会遇到很多切片问题。 对于多态对象,通常需要保存指向对象的指针或引用,以防止切片。正如我的第一点,这通常是不可取的,并使内存管理更加困难。
您的代码的读者是否会理解
基本上,你的界面和现代C++没有那么好,我们更喜欢
顺便说一下,您的虚拟基类忘记了虚拟析构函数。这是个明显的错误。 最后,我有时使用PIMPL的一个简单变体来减少样板代码的数量,这是为了让“外部”对象访问内部对象的数据成员,这样就避免了复制接口。外部对象上的函数直接从内部对象访问所需的数据,或者在内部对象上调用辅助函数,而外部对象上没有等效的辅助函数。
在您的示例中,您可以删除函数并
then you only have to implement one
|
![]() |
2
1
实际上,这只是一个设计决策。即使你做出了“错误”的决定,也不难改变。
PIMPL还用于在堆栈上提供ligthweight对象,或者通过引用同一个实现对象来呈现“副本”。
C++中的接口通常更多地用于策略,比如您希望能够选择实现的方式,尽管这不是必需的。 |
![]() |
DXZ · 有没有一种方法可以防止在编译时包含没有头保护的头文件? 6 月前 |
![]() |
gcc · C++头中的哪些关键字将进入cpp文件? 1 年前 |
![]() |
Alix Blaine · 标头预处理器唯一ID生成C++ 1 年前 |
![]() |
slim71 · C++正在初始化头文件中的类成员 1 年前 |