【问题标题】:Polymorphic templated classes with polymorphic template parameters具有多态模板参数的多态模板类
【发布时间】:2012-12-26 21:03:06
【问题描述】:

在一个简单的设计中,B 类多态地继承了 A 类。 模板类Base<T> 有一个T* 成员,用于进一步操作。 Derived<T> 多态地继承自 Base<T>。 允许创建这种对象的语法是什么:

Base<A>* a = new Derived<B>();

为了进一步参考,我使用的代码是这样的(当然转换不成功):

class A
{
public:
  A()
  {
    cout<< " A  ";
  }
  virtual void one()
  {
    cout<<" 1 ";
  }

};

class B: public A
{
public:
  B()
  {
    cout << " B  ";
  }
  void one()

  {
      cout << " 2 ";
  }
};

template <class T>
class Base
{

public:
    T* thing;
  Base()
  {
    cout<<"Base";
    thing = new T;
  }
  template <class S>
  Base(Base<S>* obj)
  {
    thing = obj->thing;
  }
  virtual void poly(){ thing->one();}
};
template <class T>
class Derived : public Base<T>
{
public:
  Derived()
  {
    cout << "DERIVED ";
  }
  virtual void poly(){ 
};
int main(int argc, char** argv)
{
  //Base<A>* a = (new Derived<B>());
  return 0;
}

为了代码简洁,故意省略了虚拟析构函数和适当的内存管理。

EDIT :这种构造的唯一目的是将BaseTemplated&lt;BasePolymorphic&gt;* 指针列表保持在一起,而不是对a 的所有N 个子类使用BaseTemplated&lt;Derived1&gt;BaseTemplated&lt;DerivedN&gt;基类,多态类。

【问题讨论】:

    标签: c++ templates inheritance polymorphism idioms


    【解决方案1】:

    首先,告诉我什么时候进入“简单化”的部分。

    剥离所有一半的模板,只专注于您尝试变形的部分)。最终你有不同的类Base&lt;A&gt;Base&lt;B&gt;。 (后者通过Derived&lt;B&gt;的推导)。

    这些都不是从它们各自的模板参数中继承。因此AB 的关系(分层或其他)是无关紧要的。 Base&lt;A&gt;Base&lt;B&gt; 是不同且不相关的,因此您尝试执行的操作无法正常工作。事实上,即使 did 分别继承自 AB,您最希望得到的还是 A* 指针,您没有在示例中使用它。

    如果另有说明,我会很高兴删除它,因为我真的很好奇。

    【讨论】:

    • 从数学上讲,这个方案应该是有意义的:A&lt;-BBase&lt;T&gt; &lt;- Derived&lt;T&gt;Base&lt;A&gt; &lt;- Derived&lt;B&gt;(我真的不知道怎么称呼它,也许是某种与协方差相关的机制)。这就是我想要达到的目标。有趣的是,我想我在某处看到了类似的东西并且它有效,但我从来没有花时间阅读那个代码装置。总而言之,简单化的部分只是“想法”——我想知道这个或类似的东西在 C++ 中是否在语义上有效(如果是,如何?)。
    • @teodron 据我所知,它不可能与您在这里的构造有关。 Base&lt;A&gt; 和 Base 最终是不相关的。他们每个人都有一个属于他们自己的多态层次结构的成员变量是不相关的。 Base 扩展仍然是不相关的。我希望这在我的描述中有意义。
    • 谢谢,我尝试重新考虑设计。
    • 是的,您要实现的是类型之间的协变关系。由于 C++ 模板是不变的,所以这是行不通的。
    【解决方案2】:

    一袋苹果Base&lt;B&gt;不是一袋水果Base&lt;A&gt;,因为你可以在一袋水果中放一个桃子、一个樱桃和一个梨。

    【讨论】:

      【解决方案3】:

      这不适用于指针。 new Derived&lt;B&gt; 的结果不能分配给Base&lt;A&gt;*,事实上它甚至不能分配给Derived&lt;A&gt;*,因为所有这些类型都是不相关的。你真的需要模板包装器之间的这种关系吗?保证Base&lt;B&gt;Base&lt;A&gt; 的值的可转换性还不够吗(就像标准的智能指针那样)?您已经使用模板化转换构造函数获得了这个...

      //...
      Base<B> tB(new B);
      Base<A> tA = tB;
      //...
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多