可以通过预处理宏来控制重复包含的问题
如果是模板类,那么类成员函数声明为内联的即可
例如
//A.h
#pragma once
#include "B.h"
template<typename T> class B;
template<typename T> class A
{
public:
A(B<T>* b=NULL):b_(b){};
void SetPtr(B<T>* b)
{
b_ = b;
}
void CallFuncFromB()
{
b_->PrintfB();
}
void PrintfA()
{
cout<<"PrintfA"<<endl;
}
public:
B<T>* b_;
};
//B.h
#pragma once
#include "A.h"
template<typename T> class A;
template<typename T> class B
{
public:
B(A<T>* a=NULL):a_(a){}
void SetPtr(A<T>* a)
{
a_ = a;
}
void CallFuncFromA()
{
a_->PrintfA();
}
void PrintfB()
{
cout<<"PrintfB"<<endl;
}
public:
A<T>* a_;
};
//main.cpp
#include <iostream>
#include "A.h"
using namespace std;
int main(int argc, char** argv)
{
A<int> a;
B<int> b;
a.SetPtr(&b);
b.SetPtr(&a);
a.CallFuncFromB();
b.CallFuncFromA();
system("pause");
return 0;
}
//这种方法有一种限值条件,就是模板类A和B的模板参数要求一致。
追问用#pragma once会不会导致下列问题:
一个头文件先被执行;然后这个头文件被包含,但是因为#pagma once,里面的声明不会再执行一遍,结果导致“未声明标识符”
内联是指inline吗?为什么内联就行了?
追答或者你都不include对方的头文件,直接前置声明也一样的
内联就是inline ,为什么要内联这是由于当时C++98标准没有解决这一问题而编译器厂家委婉的一种做法,具体google之。
追问1.首先感谢你~那段代码能用。
直接前置声明,如template class B; 不包含头文件,那不就没有声明成员函数吗?这样也能调用B的方法?
另外能不能再给一个例子:一个类泛型,另一个类不泛型。
2.加上inline解决什么问题?解决不能相互包含,还是解决泛型类的实现和声明不能分开?如果比较长的函数,编译器不会按照内联来编译,这样还有效吗?
追答模板类只有在实例化的时候才去找成员函数的定义,在main.cpp里POI(初始化点)的时候是能找到双方的函数定义的(你include了)
inline是大多数编译器厂家的做法,叫做包含模型(这样在头文件里加入inline后就可包含实现),因为当时要实现export的分离模型很难,现在最新的C++11应该实现了该做法
再给你一个例子吧 记得结贴哦!
//C.h
#pragma once
#include "D.h"
template<typename T> class C
{
public:
C(D* d=NULL):d_(d){};
void SetPtr(D* d)
{
d_ = d;
}
void CallFuncFromD()
{
d_->PrintfD();
}
void PrintfC()
{
cout<<"PrintfC"<<endl;
}
typedef T CT;
private:
D* d_;
};
//D.h
#pragma once
class D
{
public:
D(void* c=NULL):c_(c){}
void SetPtr(void* c)
{
c_ = c;
}
void PrintfD()
{
std::cout<<"PrintfD"<<std::endl;
}
template<typename T>
void CallFuncFromC()
{
C<T>* p = static_cast<C<T>*>(c_);
p->PrintfC();
}
private:
void* c_;
};
//main.cpp
#include <iostream>
#include "C.h"
using namespace std;
int main(int argc, char** argv)
{
C<int> c;
D d;
c.SetPtr(&d);
d.SetPtr(&c);
c.CallFuncFromD();
d.CallFuncFromC<C<int>::CT>();
system("pause");
return 0;
}
一个模板,一个非模板 非模板的一定要声明为模板成员函数才能调用模板类的方法!切记!