我有两个具有不同 header 的类:class Renderer
和 class Texture
。 Texture
实例旨在管理驻留在 Renderer
内存池中的一些数据,因此 Texture
实例不能独立于Renderer
实例。要获取 Texture
实例的句柄,只需使用正确的文件名调用 Renderer::loadTexture
,然后 Renderer
在其数据库中搜索 Texture
具有匹配文件名的对象,如果未找到匹配项,则实例化一个新纹理。
//renderer.h
#include "texture.h"
class renderer
{
public:
Texture* loadTexture(std::string fileName);
private:
std::map<std::string, Texture*> textureDb;
};
//texture.h
class Texture
{
public:
Texture(std::string imageFileName);
};
我突然想到,将 class Texture
的构造函数设为私有(private)并声明 Texture * Renderer::loadTexture(std::string filename)
是合乎逻辑的作为 class Renderer
的 friend :
//renderer.h
#include "texture.h"
class renderer
{
public:
Texture* loadTexture(std::string fileName);
private:
std::map<std::string, Texture*> textureDb;
};
//texture.h
class texture;
#include "renderer.h"
class Texture
{
private:
Texture(std::string imageFileName);
Texture(const Texture &);
friend Texture* loadTexture(std::string);
};
但是,只有在包含 renderer.h 之前始终包含 texture.h 时,这才会编译,因为 class Texture
要求 class Renderer
已经定义。防止这种情况的最佳方法是什么? Include 守卫出现在两个文件中,但为简洁起见此处省略。
最佳答案
首先,也是最重要的,在上面的代码中,尽可能前向声明。这应该有点帮助。
// Renderer.h
class Texture;
class Renderer {
...
};
// Renderer.cpp
#include "Renderer.h"
#include "Texture.h"
...
// Texture.h
//class Renderer; // looks like this isn't needed
class Texture {
...
};
// Texture.cpp
#include "Renderer.h"
#include "Texture.h"
...
通过前向声明,您应该足以在 Renderer 类 header 中声明指向 Texture 的指针。看起来这就是您现在所需要的;将其余部分推送到 Renderer.cpp。
接下来,避开 friend ;但是,在这种情况下它可能是可以接受的。
最后,循环依赖从来都不是一件好事。看看你是否可以稍微改变一下你的设计。看看你是否可以引入一个接口(interface)或抽象基类来打破你的循环依赖。看起来 Renderer 根本不需要依赖 Texture。
相反,考虑重写 Renderer 以依赖于某种 ITexture 接口(interface),然后让 Texture 实现 ITexture:
class ITexture
{
// no data members
// no method bodies
// only pure virtual method declarations
};
class Renderer
{
public:
ITexture* loadTexture(std::string fileName);
private:
std::map<std::string, ITexture*> textureDb;
};
class Texture : public ITexture
{
...
};
关于c++ - 类声明的循环依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21692399/