首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >及时推导

及时推导
EN

Stack Overflow用户
提问于 2009-12-17 11:51:16
回答 9查看 695关注 0票数 8

有一个不太常见的C++成语,我在过去已经用过几次了。我只是不记得它是否有一个常用的名称来描述它。

它在某种程度上与混和剂CRTP类型擦除有关,但并不是其中的任何一件。

当您想要向类中添加一些实现时,就会发现这个问题,但是您不想将它放入类或它派生的任何类中。其中一个原因可能是类可能是继承层次结构的一部分,在继承层次结构中,实现应该只发生一次。

暂且不考虑诸如层次结构是否应该有具体的非叶类,或者在某些情况下虚拟继承是否是一种选项等问题,我知道在模板类中提供从其模板参数派生出来的实现的解决方案。这样,您就可以在创建实例时使用模板,但只能通过指针或对其基的引用来使用对象(在松散的意义上,类型擦除就是在这种情况下出现的)。

例如,您可能有一个侵入性引用计数。您的所有类都是从ref计数接口派生的,但是您只想让ref计数本身和ref计数方法的实现出现一次,所以将它们放到派生的模板中--让我们称其为ImplementsRC<T>。现在您可以创建如下所示的实例:

代码语言:javascript
复制
ConcreteClass* concrete = new ImplementsRC<ConcreteClass>();

我正在处理一些事情,如由多个模板重载组成的转发构造函数等。

所以,希望我已经说清楚了这个成语是什么。现在回到我的问题--这个成语有一个被接受的,或者至少被普遍使用的名字吗?

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2009-12-17 20:45:46

我肯定认为这是一个混合体,Bruce (http://www.artima.com/weblogs/viewpost.jsp?thread=132988)也是。

在我看来,它仍然是单一继承,这与使用MI实现类似的目标不同。

票数 1
EN

Stack Overflow用户

发布于 2009-12-17 18:18:57

这是个有趣的主意。然而,我不会在这里给你一个已经确定的模式的名字,相反,我要解释为什么我认为它已经没有了。

它是做什么的?

这是一个非常好的方法,以避免可怕的钻石继承。

既然这个方法的目的似乎有些混乱,我想解释一下,为何我认为这是目的:

代码语言:javascript
复制
class RefCounted
{
  virtual void addReference() = 0;
  virtual void removeReference() = 0;
};

class B: public RefCounted {};
class C: public RefCounted {};

class Diamond: public B, public C {};

现在,我们这里有个问题。如果我们将RefCounted的实现正确地放在这个类中,它将变成一个基类而不是一个接口,因此我们必须使用虚拟继承,否则数据成员将被复制(同时出现在B和C中)。

因此,我们的想法是把执行工作推迟到最后一刻。

优势:

  • 不需要尝试事后猜测B或C的使用:虚拟继承在那里是不必要的。
  • 如果您忘记添加实现,编译器将很好地提醒您,因此不需要担心这个问题。

不便的:

  • 给客户端增加负担:您最好有一个工厂来创建对象,特别是因为一个对象可以实现各种接口!请注意,这可以通过模板元编程(或多或少)实现自动化,或者可以由类作者提供。

提供以下内容的例子:

代码语言:javascript
复制
// d.h
class D: public B, public C
{
public:
  typedef ImplementRC<D> concrete_type;
  static concrete_type Build(int, int); // Named Constructor idiom

private:
  D(int,int);
}; // class D

// main.cpp
D::concrete_type myD = D::Build(1,2);

,那叫什么名字?

我想不出任何与此完全相符的东西。桥和装饰已经被提到,但这是相当特别的,实际上也不是面向对象的(例如,它不会发生在Java中,因为您没有多重继承),所以我怀疑GoF的书中是否会找到这个术语。

而且,它并不是真正的CRTP,因为CRTP (基本知道它的派生类)中有一种循环不会在这里发生>我们确实是严格线性的!

然后,它肯定不是Pimpl成语,它建议将实现隐藏在客户端之外,同时使用模板来实现,只需将其抛到脸上就行了!(模板可以使用Pimpl作为内部细节)

我谦逊地建议jiti及时实现,这在某种程度上模仿了标题,但更接近我认为的点,这里的派生只是一个工具,而不是一个目标。

无论如何都是个有趣的想法。

票数 3
EN

Stack Overflow用户

发布于 2009-12-17 12:49:09

我不确定它是否有名字,就像gf建议的那样,它看起来有点像桥型。这几乎就像将功能与基类挂钩一样。

我建议用一个新的名字,皮条客成语。因为你在拉皮条你的基类;)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1921232

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档