【问题标题】:C++ Template Container InheritanceC++ 模板容器继承
【发布时间】:2013-11-14 18:39:47
【问题描述】:

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

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

== 编辑 ==

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

【问题讨论】:

  • 你能提供一个aContainer的用例吗?
  • 我不认为你可以在 C++ 中拥有这样的东西。另外,避免裸指针,改用智能指针(否则你需要手动释放它们)
  • 最接近您的代码的是; B b = B(); Container&lt;B&gt; bContainer = aContainer&lt;B&gt;(b); A* a = bContainer._t;
  • 您必须等待concepts 被添加:isocpp.org/blog/2013/02/…
  • @YuliaV 这里的好建议是:完全避免使用指针。使用静态分配。

标签: java c++ templates generics inheritance


【解决方案1】:

如果您使用的是 C++11(或可能是 boost),您可以使用 std::is_base_of&lt;A,B&gt;,如果 A 是 B 的基类,则包含 (value=) true。

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

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

如果您尝试使用append(derived),请考虑container&lt;base&gt;,这很好,因为指向派生的指针可以转换为基指针。

但是,这可以让您拥有任何内容的列表。

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

static_assert(!std::is_base_of&lt;base,T&gt;::value,"You must derive from base");

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

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

【讨论】:

    【解决方案2】:

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

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

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

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

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

    【讨论】:

    • 这不是 C++ 应该工作的方式。避免指针和动态分配,不要建议有人像在 Java 中一样用 C++ 编程。是非常不同的语言。
    • 我不觉得这个答案表明我应该像 Java 那样编写 C++。为了简单起见,我的问题中的示例是用指针编写的。任何有经验的程序员都会意识到不同的语言在不同的范式上运行。事实上,这就是问题的核心所在。
    猜你喜欢
    • 2011-04-17
    • 1970-01-01
    • 2012-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多