C ++模板容器继承

时间:2013-11-14 18:39:47

标签: java c++ templates generics inheritance

在Java荒野中度过了太多时间后,我对C ++有点新鲜。

假设我有数据类A和B以及容器类,我将其称为Container:

class A
{
public:
  virtual void foo()
  {
    cout << "I am an A" << endl;
  }
};

class B : public A
{
public:
  void foo()
  {
    cout << "I am a B" << endl;
  }
};

template <class T> class Container
{
public:
  T *_t;

  Container(T *t)
  {
    _t = t;
  }
};

我希望看起来像

的Java等价物
B b = new B();
Container<? extends A> aContainer = new Container<B>(b);

如何在C ++中完成?这甚至是规范的吗?

以下代码给出了编译错误:

B *b = new B();
Container<A> *aContainer = new aContainer<B>(b);

到目前为止,谷歌一直没有帮助找到“?extends”的等价物。

==编辑==

解决方案是重写我的代码,以便不需要“?extends”,正如Isaac Drachman在下面描述的那样。

2 个答案:

答案 0 :(得分:0)

如果您正在使用C ++ 11(或者可能是boost),那么如果A是B的基类,则可以使用包含(value =)true的std::is_base_of<A,B>

无论如何,你可以这样做:

template<class T>
class container {
    void append(T* what);
}

考虑container<base>如果你尝试做append(derived)它没关系,因为指向派生的指针可以转换为基指针。

然而,这可以让你有一个任何列表。

如果你想控制它,比如Java中的“extends”;

static_assert(!std::is_base_of<base,T>::value,"You must derive from base");

坚持到某个地方并得到一个很好的错误信息“你必须从基地派生”

使用模板无法指定“T extends B”,因为模板系统复杂且更高级(能够执行更多操作),因此如果您指定具有相同方法名称的类型,则可以通过更改工作,或者您如果您错过了一个似乎没有告诉您错过方法名称的方法名称,则可能会出现可怕的错误。

答案 1 :(得分:-1)

您对A,B和Container类的声明是有效的,并且可以用于此目的。以下语法导致错误。

B *b = new B();
Container<A> *aContainer = new aContainer<B>(b);

首先,当对new的类使用构造函数时,需要使用类名(如Java中),而不是对象。至于继承方面,您的容器被声明为Container<A>,因此无法构造为Container<B>,即使B继承自A。使用Container<A>类型和构造函数为您的{{1}对象将允许您包含A对象或B对象,这是我认为您正在尝试做的事情。因此,您的代码应如下所示:

aContainer

编译并且应该对你有用。随意解释这是否适合您的想法。希望它有所帮助!