问题:
在一个项目中有两个类 A 和 B ,分别对应 四个 文件 A.h, A.cpp, B.h, B.cpp。内容如下:
A.h
#pragam once
#include "A.h"
class A
{
public:
A();
~A();
int mI;
int f();
B* b;
};
B.h
#pragam once
#include "B.h"
class B
{
public:
B();
~B();
int mI;
int f();
A* a;
};
A.cpp
#include "A.h"
A::A()
{
<span style="white-space:pre"> </span>mI = 10;
}
A::~A()
{
}
int A::f()
{
<span style="white-space:pre"> </span>return mI;
}
#include "B.h"
B::B()
{
<span style="white-space:pre"> </span>mI = 20;
}
B::~B()
{
}
int B::f()
{
<span style="white-space:pre"> </span>return mI;
}
注意其中 A.h,B.h 互相包含了。
编译.....妥妥的报错了。。
解决方案:
首先看看这个链接:
查看一下预编译文件
A.i
#pragma once
#pragma once
class B
{
public:
B();
~B();
A* a;
};
class A
{
public:
A();
~A();
B* b;
};
A::A()
{
}
A::~A()
{
}
B.i
#pragma once
#pragma once
class A
{
public:
A();
~A();
B* b;
};
class B
{
public:
B();
~B();
A* a;
};
B::B()
{
}
B::~B()
{
}
这里可以看出问题,A, B 申明有个先后顺序,所以总有一个不能找到声明。并且还有可能造成重复定义。
接着我们就对症下药。
先看 A.h, 在其中有个 B 类型的指针,既然是指针类型,编译器就已经知道了,这个地方占用 4 个字节就行了, 我们只需要告诉编译器,有 B 这个类型即可,至于 B 里面包含了什么东西, 编译器 这时不必要知道,只是在 B 构造的那一刻, 才需要 B 里面是什么内容。
我们改一下:
A.h
#pragma once
class B;
class A
{
public:
A();
~A();
int mI;
int f();
B* b;
};
B.h
#pragma once
class A;
class B
{
public:
B();
~B();
int mI;
int f();
A* a;
};
A.cpp
#include "A.h"
#include "B.h"
A::A()
{
mI = 10;
}
A::~A()
{
}
int A::f()
{
b = new B();
return b->f();
}
B.cpp
#include "B.h"
#include "A.h"
B::B()
{
mI = 20;
}
B::~B()
{
}
int B::f()
{
a = new A();
return a->f();
}
再编译一次 OK了。
接着 再看看预编译文件
A.i
#pragma once
class B;
class A
{
public:
A();
~A();
int mI;
int f();
B* b;
};
#pragma once
class A;
class B
{
public:
B();
~B();
int mI;
int f();
A* a;
};
A::A()
{
mI = 10;
}
A::~A()
{
}
int A::f()
{
b = new B();
return b->f();
}
B.i
#pragma once
class A;
class B
{
public:
B();
~B();
int mI;
int f();
A* a;
};
#pragma once
class B;
class A
{
public:
A();
~A();
int mI;
int f();
B* b;
};
B::B()
{
mI = 20;
}
B::~B()
{
}
int B::f()
{
a = new A();
return a->f();
}
至此,就可以使用A 和 B 了。
使用:
main.cpp#include <iostream>
#include "A.h"
#include "B.h"
int main()
{
A a;
std::cout << a.f() << std::endl;
system("pause");
return 0;
}
main.i
#pragma once
class B;
class A
{
public:
A();
~A();
int mI;
int f();
B* b;
};
#pragma once
class A;
class B
{
public:
B();
~B();
int mI;
int f();
A* a;
};
int main()
{
A a;
std::cout << a.f() << std::endl;
system("pause");
return 0;
}