c++ - 类声明的循环依赖

标签 c++ friend circular-dependency

我有两个具有不同 header 的类:class Rendererclass TextureTexture 实例旨在管理驻留在 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/

相关文章:

c++ - 使用位域转换大型项目以使用更便携的东西

c++ - 有趣的代码行为

c++ - 什么时候必须使用友元函数而不是成员函数?

c++ - 为什么只有在使用公共(public)继承时派生类的友元函数为 "available"?

C++ Circular #include 前向声明未修复

javascript - Node.js 中如何处理互包含?

java - Gradle:如何管理对测试实用程序的循环依赖

c++ - 添加两个号码。无需任何运算符(operator)

c++ - 使用一个动态分配的内存块创建 2d 或 3d 数组

c++ - 是否可以在 C++11 中手动设置 istream 失败位