0

在 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);

到目前为止,谷歌在寻找“?扩展”的等价物方面一直没有帮助。

== 编辑 ==

解决方案是重写我的代码,以便不需要“?扩展”,如下面的 Isaac Drachman 所述。

4

2 回答 2

0

如果您使用的是 C++11(或可能是 boost)std::is_base_of<A,B>,如果 A 是 B 的基类,则可以使用 which contains (value=) true。

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

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

考虑container<base>一下是否尝试这样做append(derived)很好,因为指向派生的指针可以转换为基指针。

但是,这使您可以列出任何内容。

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

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

把它贴在某个地方并得到一个很好的错误消息“你必须从基础派生”

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

于 2013-11-14T18:45:54.703 回答
-1

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

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

首先,当使用带有 a 的类的构造函数时new,您需要使用类名(就像在 Java 中一样),而不是对象的。至于继承方面,您的容器被声明为Container<A>,因此不能构造为 a Container<B>,即使 B 从 A 继承。Container<A>为您的对象使用类型和构造aContainer函数将允许您包含 A 对象或 B 对象,这就是我认为你正在尝试做。因此,您的代码应如下所示:

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

编译并且应该为你工作。如果这不适合您想要做的事情,请随时解释。希望它有所帮助!

于 2013-11-14T18:51:53.480 回答