C++中的模板类如何前置声明派生类

3

我在设计实现中遇到了一些问题。大致是这样的:

我有一个模板基类,其中包含一个转换方法。

// 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,而Bar.h又包含了Foo.h(因为它是一个模板)。
哦,只是为了明确起见,所有头文件都使用了包含保护。
#ifndef _HEADER_NAME_H_
#define _HEADER_NAME_H_
...
#endif

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

举个更具体的例子,比如我有一个数组类(Array class),它有一个将其转换为可读性较强的字符串(String class)的方法,例如toString()...然而,这个String类被声明为

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

感谢您的提前帮助。 Gary。


也许使用指针作为返回值,而不是实例本身? - Griwes
在模板中使用虚函数似乎有些不妥。这似乎是将两个不同的概念混合在一起(多态性与特化)。 - Skizz
@Skizz 这是为了让派生类具有扩展和重写的能力。也许我可以使用特化和 typedef 代替?例如:typedef Array<char> String;template<> class Array<Char> { String toSting(); /* String 特定的专门化方法(例如 trim 等)*/ } - Gary Doublé
@Skizz:你听说过基于将模板与虚函数混合的类型抹除技术吗?不过这似乎不是OP的情况。 - K-ballo
@Gary:我的意思是,虚拟(virtual)意味着一个共同的基类,而模板(templates)则是不同的类。因此,我会这样写:template<typename T> class Foo : public IBaseClass { },并将 IBaseClass 定义为一个纯虚基类。 - Skizz
@K-ballo:不,我没有听说过那些...去谷歌搜索一下... - Skizz
2个回答

1
为了使 Foo< float > 成为一个基类,它必须在 Bar 定义的时候已经完全定义。然而,如果你能让 Bar 成为 Foo 中的一个依赖类型,那么 Foo 并不一定需要知道 Bar 的存在。
在定义 Foo 之前,对 Bar 进行前向声明可能就足够了。如果您发布/链接更具体的代码,我可能能够给您更好的答案。
试试这个:
class Bar;

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

    virtual const DependantBar toBar();

}

0
class Bar : public Foo<float> {
    template <typename T>
    Bar create(const Foo<T>&);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接