具有模板化派生类的工厂模式会导致循环头依赖

时间:2018-10-21 08:29:53

标签: c++ templates factory circular-dependency

由于某种原因,我必须将基类和派生类的声明分隔为不同的标头。派生类是模板化的,而Base不是。因此,我正在执行以下操作:

base.h:

#pragma once
#include "foo.h"
#include "derived.h" // Without it, I can't write the factory method

class Base {
public:
    Base () = default;
    template <typename T> // Because of template, this must be placed in header
    static std::unique_ptr<Base> get (bool derived, Foo<T> *foo) {
        if (!derived)
            return std::make_unique<Base> ();
        return std::make_unique<Derived<T>> (foo);
    }
    void do_stuff () { /* some simple code */ }
};

derived.h:

#pragma once
#include "foo.h"
#include "base.h"

template <typename T>
class Derived : public Base {
    Foo<T> *foo;
public:
    Derived (Foo<T> *foo) : foo (foo) { };
    void do_stuff ();
};

derived.cpp:

#include "derived.h"

template <typename T>
void Derived<T>::do_stuff () { /* some code using foo */ }

template class Derived<T1>; // T requires explicit specialization
template class Derived<T2>;
template class Derived<T3>;

external.cpp:

#include "base.h"
...
auto bar = Base::get (some_bool, &foo);
bar->do_stuff();

如您所见,它是循环头依赖项。

如果我对整个Base类进行模板化,则可以将Base::get ()放在.cpp文件中,将derived.h放入其中,并避免将derived.h放入base.h中。但是,此解决方案需要对Base<T1>Base<T2>等进行显式专门化。这看起来很丑,因为T仅在工厂方法中使用,并且T有9种专门化。

那么,在这种情况下最好的方法是什么?

UPD 来自建议问题的答案不适合该问题,因为此处无法使用前向声明和类指针/引用。而且,我不是问为什么不起作用;我在问一种通用的方法。

0 个答案:

没有答案