![]() |
1
0
我认为你是对的,因为我一开始不理解你的问题。 我想你是想把一个方形的东西压成一个圆孔…它不太适合C++。 你 可以 强制容器保存指向给定基本布局对象的指针,然后允许从那里实际指向任意组合的对象,假设您作为程序员实际上只放置具有相同内存布局的对象(成员数据-没有类的成员函数布局,除非它有虚拟的,你希望避免它)。
注意:在绝对最小的情况下,您必须在ishape中定义一个虚拟析构函数,否则对象删除将失败。 你可以有一个类,所有这些类都有一个指向公共实现核心的指针,这样所有的组合都可以用它们共享的元素进行初始化(或者可以通过指针静态地作为一个模板来完成——共享数据)。 但问题是,如果我试图创建一个示例,我会在考虑到:所有形状共享的数据是什么?我想你可以有一个点的向量,它可以是任何形状所需要的大小。但即使如此,draw()确实是多态的,它不是一个可能由多个类型共享的实现——它必须为各种形状分类定制。也就是说,一个圆和一个多边形不可能共享同一个draw()。如果没有vtable(或其他动态函数指针构造),就不能改变从一些公共实现或客户机调用的函数。 您的第一组代码充满了混乱的结构。也许你可以添加一个新的,简单的例子,纯粹以一种更现实的方式显示——你想做的事情(忽略C++没有你想要的机制——只演示你的机械师应该是什么样子)。 在我看来,我只是没有得到实际的应用程序,除非你正准备做如下的事情: 采用从其他两个COM接口继承的COM类:
现在我有了一个菱形继承模式:ishellbrowser和icommdlgbrowser最终从iunknown继承。但是,编写自己的iunknown:addref和iunknown::release实现似乎非常愚蠢,这是一种高度标准的实现,因为没有办法让编译器让另一个继承的类为ishellbrowser和/或icommdlgbrowser提供缺少的虚拟函数。 也就是说,我最终不得不:
因为我不知道从其他地方“继承”或“注入”那些函数实现到myshellbrowserdialog中。 它实际上填充了所需的虚拟成员函数 对于IShellBrowser或ICommDlgBrowser。 如果实现更复杂,我可以手动将vtable链接到继承的实现者,如果我愿意:
如果我需要混入来实际引用最派生的类来与它交互,我可以向iunknownmixin添加一个模板参数,以使它能够访问我自己。 但是,我的班级能有什么共同的元素,或者说我的学生能从这些元素中获益,而这些元素本身并不能提供? 任何复合类都可以拥有哪些不同的混音器想要访问的公共元素,这些元素是它们从自身派生出来的?让mixin接受一个类型参数并访问它。如果它的实例数据是最派生的,那么您有如下内容:
最终你的问题对我来说还是有些困惑。也许你可以创建一个例子来展示你喜欢的自然语法,它能清楚地完成一些事情,因为我在你最初的文章中没有看到这个,而且我自己似乎也无法从玩弄这些想法中找到它。 |
![]() |
2
4
我应该注意到
PIMPL只是一种避免不必要的编译时依赖性的技术。 您不需要实际知道如何实现类来继承它。它会破坏封装的目的(尽管编译器会…)。 所以…我想你不是想用皮条客。我宁愿认为这是一种代理模式,因为显然:
如果要隐藏实现详细信息
使用
如果需要代理类
用素的就行了
为了继承 当您从类继承时,它的私有成员是如何实现的并不重要。所以就从中继承吧。 如果要添加一些新的私人成员(通常情况下),则:
正如您所看到的,经典实现没有太大的区别,只是有一个指针代替了一堆数据。 当心
如果你转寄申报单
问题是为了生成析构函数的代码,编译器需要定义
此外,如果您想要一份深入的副本(而不是一份浅薄的副本,它包含在副本和原始副本中,两者都指向同一个副本)
你可以决定创建一个更好的类
这很痛苦…我为你感到抱歉。 编辑:让我们进行形状讨论。
您可以看到:圆形和矩形都不关心shape是否使用pimpl,正如其名称所暗示的那样,pimpl是一个实现细节,它是一个私有的东西,不能与类的后代共享。 正如我所解释的,圆和矩形也都使用pimpl,每个都有自己的“实现类”(顺便说一下,它只能是一个没有方法的简单结构)。 |
![]() |
3
0
我已经看到许多解决这个基本难题的方法:多态性+界面的变化。 一种基本的方法是提供一种查询扩展接口的方法,因此您可以在Windows下使用COM编程的方法:
另一种选择是创建一个更丰富的基本接口类——它拥有您所需要的所有接口,然后简单地为基类中的那些接口定义一个默认的、没有op实现,它返回false或throw来表示所讨论的子类不支持它(否则子类将提供一个函数implem此成员函数的纠缠)。
我希望这能帮助你看到一些可能性。 smalltalk有一个极好的特性,即能够询问元类型系统给定的实例是否支持特定的方法,并且它支持类处理程序,该类处理程序可以在任何时候要求给定的实例执行它不支持的操作时执行,以及该操作是什么,因此您可以将其作为代理转发,或者您可以抛出一个不同的错误,或者只是悄悄地忽略该操作作为一个no-op)。 Objective-C支持与Smalltalk相同的所有模式!非常非常酷的事情可以通过在运行时访问类型系统来完成。我假设.NET可以沿着这些线拉一些疯狂的酷东西(尽管从我所看到的来看,它几乎和Smalltalk或Objective-C一样优雅)。 无论如何…祝你好运: |