【问题标题】:forward declare derived class from template c++从模板 C++ 前向声明派生类
【发布时间】:2011-11-18 06:16:24
【问题描述】:

我在解决设计实现中的一些问题时遇到了麻烦。它是这样的:

我有一个模板基类,它有一个转换方法。

// Foo.h

class Bar;

template<typename T>
class Foo {

    virtual const Bar toBar();

}

我希望派生类 Bar 从特定形式的 Foo 继承,例如:

// Bar.h
class Bar : public Foo<float> {
    // Insert Bar methods here, Etc.
}

由于 Foo 是一个模板,因此必须在头文件中完全定义实现,这会导致 toBar() 方法的实现需要能够创建 Bar 类型的实例的问题。所以这告诉我我需要在 Foo 定义之后但在 Foo 实现之前包含 Bar.h 头文件。

但是,在 Bar.h 中,类 Bar 派生自 Foo,因此必须提供 Foo 的完整定义。这会导致问题,因为这两个文件具有循环依赖,无法通过前向声明解决,因为前向声明是派生类。

如果另一个类 SomeClass 有一个 Bar 类型的数据成员,这会变得更加复杂,因为这需要包括 Bar.h ,其中包括 Foo.h (因为它是一个模板) 包括 Bar.h。

哦,为了清楚起见,所有头文件都使用了包含保护

#ifndef _HEADER_NAME_H_
#define _HEADER_NAME_H_
...
#endif

其他人是如何解决此类复杂问题的?

作为一个更具体的例子,我有一个 Array 类,它有一个方法可以将它转换为人类可读的 String 类,例如 toString()...但是 String 类被声明为

class String : public Array<char> {...};

提前致谢。 加里。

【问题讨论】:

  • 也许使用指针而不是实例本身作为返回值?
  • 模板中的虚拟有点臭。似乎将两种不同的想法混合在一起(多态性与专业化)。
  • @Skizz 是为了让派生类有扩展和覆盖的能力。也许我可以使用 sspecialisation 和 typedef 来代替?例如:typedef Array 字符串;模板 类 Array { String toSting(); /* 字符串特定的特化方法(比如修剪等 */ }
  • @Skizz:听说过基于混合模板和虚函数的类型擦除技术吗?并不是说这里似乎是 OP 案例。
  • @Gary:我的意思是,虚拟意味着一个通用的基类,模板是不同的类。所以我有:template&lt;typename T&gt; class Foo : public IBaseClass { } 并将IBaseClass 定义为纯虚拟基类。

标签: c++ class templates forward derived


【解决方案1】:

为了使Foo&lt; float &gt; 成为基类,它必须已完全由Bar 定义点定义。但是,Foo 不一定需要知道 Bar,如果您可以使 Bar 成为 Foo 中的依赖类型名。

在定义Foo 之前先声明Bar 可能就足够了。如果您发布/链接更具体的代码,我可能会给您一个更好的答案。

试试这个:

class Bar;

template< typename T, typename DependantBar = Bar >
class Foo {

    virtual const DependantBar toBar();

}

【讨论】:

    【解决方案2】:
    class Bar : public Foo<float> {
        template <typename T>
        Bar create(const Foo<T>&);
    }
    

    【讨论】:

      猜你喜欢
      • 2021-05-28
      • 2012-06-06
      • 2020-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多