模板类中的循环依赖

时间:2013-09-18 14:32:20

标签: c++ templates polymorphism

我将循环依赖简化为以下内容:

// Bar.h
struct Bar {};

// Base.h
#include "Foo.h"
struct Bar;
struct Base {
    void func(std::shared_ptr<Foo<Bar>> foobar); // use methods of Foo in some way.
};

// Derived.h
#include "Base.h"
struct Derived : public Base {};

// Foo.h
#include "Derived.h"
template <typename T>
struct Foo {
    void func(std::shared_ptr<Derived> d) {
        // use methods of Derived in some way.
    }
};

我不能简单地在Foo中声明Base.h,因为它是一个模板类,由于多态性,无法在Base中转发声明Derived.h,并且无法在Derived中转发声明Foo.h,因为Foo::func使用Derived的成员。

我之前已经阅读过将模板实现与声明分离的想法,因为我不知道最佳实践并且不确定它是否适用于这种情况。这两个DerivedFoo在我的整个计划中得到广泛使用。

如何解决此依赖关系?

2 个答案:

答案 0 :(得分:2)

声明一个std::shared_ptr<type>的函数不需要type的完整定义,所需要的只是(前向)声明。这允许您避免#include Derived.h(在Foo.h中)和/或Foo.h(在Base.h中)

答案 1 :(得分:0)

在相互引用的类中启用内联函数:

标题A.h

struct B;
struct A { 
    void a() {}
    void f();
    std::shared_ptr<B> b;
};
#include "A.tcc"

标题A.tcc

#include B.h
inline void A::f() { b->b(); }

标题B.h

struct A;
struct B { 
    void b() {}
    void f();
    std::shared_ptr<A> a;
};
#include "B.tcc"

标题B.tcc

#include A.h
inline void B::f() { a->a(); }

请确保所有文件都有标题保护!