模板类和非模板类的循环依赖关系

时间:2012-02-11 14:18:50

标签: c++ templates

文件ex1.hpp(模板类的定义):

#ifndef EX1_HPP
#define EX1_HPP

#include "ex2.hpp"

template <class T>
class Ex1{
public:
    void Ex1method(){
        Ex2 a; // using nontemplate class object
        a.Ex2method();
    }
};

#endif

文件ex2.hp​​p(nontemplate类的定义):

#ifndef EX2_HPP
#define EX2_HPP

#include "ex1.hpp"

class Ex2{
public:
    void Ex2method();
};

#endif

文件ex2.cpp(nontemplate类方法的定义):

#include "ex2.hpp"

void Ex2::Ex2method()
{
    Ex1<int> e; // using template class object
    e.Ex1method();
}

编译错误:

ex1.hpp:10:9: error: ‘Ex2’ was not declared in this scope
ex1.hpp:10:13: error: expected ‘;’ before ‘a’
ex1.hpp:11:9: error: ‘a’ was not declared in this scope

如何解决nontemplate类和模板类之间的这种循环依赖关系?我无法将nontemplate类方法定义为实现文件,因为它会导致链接器错误。如果我在文件ex1.hpp中放置Ex2类的声明,那么错误是:

error: invalid use of incomplete type ‘struct Ex2’
error: forward declaration of ‘struct Ex2’

4 个答案:

答案 0 :(得分:3)

请勿在{{1​​}}中加入ex1.hpp,因此没有必要。您的标题没有循环依赖。

ex2.hpp文件中包含两个标题(或只是ex1.hpp),一切都应该是好的。

答案 1 :(得分:1)

从ex2.h,移动

#include "ex1.hpp"

到ex2.cpp

答案 2 :(得分:1)

根本不需要ex1.hpp ex2.hpp。从ex2.cpp包含它,而循环依赖将会消失。

答案 3 :(得分:1)

如果Ext1中确实需要Ext2,例如Ext1中有Ext2成员,您仍然可以使用Ext2取决于T。然后,当实际调用模板的成员函数时,您只需要Ext2的完整定义。

class Ext2;

template <class T, class>
class Identity {
    typedef T type;
};

template <class T>
class Ex1{
public:
    void Ex1method(){
        typename Identity<Ex2, T>::type a;
        a.Ex2method();
    }
};

现在,如果Ext1method的用户希望调用该成员函数,则可以包含Ext2的标头。现在不再需要在Ext2.hpp中添加Ext1.hpp了。但是这种并发症只有在

时才需要或有用
  • 您无法在Ext1.hpp
  • 中省略Ext2.pph
  • 您不希望不呼叫Ext1method的用户自动包含Ext2.h(“名称污染”)。