gpt4 book ai didi

c++ - 在多个 DLL 中分离类实现

转载 作者:行者123 更新时间:2023-11-30 05:20:22 27 4
gpt4 key购买 nike

我正在尝试创建一个系统,该系统在每个 dll 中使用一个类的不同实现。所以我有一个 VertexBufferObject 类,它有一个实现和私有(private)方法(也许是该 DLL 严格使用的方法)。但是主要可执行文件只会使用一组特定的方法。例如:

在 openglGraphics.dll 中:

class VertexBufferObject {
private:
// Unexported data
uint vbo;

// Exported data (won't actually use this though)
std::vector<Vec3> arr;
public:
// Unexported methods
IDirect3DVertexBuffer9 *getVBO();

// Exported methods
virtual void Build(Vec2 array);
virtual void Build(Vec3 array);
virtual void Unbind();
~VertexBufferObject();
};

在 directXGraphics.dll 中:

class VertexBufferObject {
private:
// Unexported data
IDirect3DVertexBuffer9 vbo;

// Exported data (won't actually use this though)
std::vector<Vec3> arr;
public:
// Unexported methods
IDirect3DVertexBuffer9 *getVBO();

// Exported methods
virtual void Build(Vec2 array);
virtual void Build(Vec3 array);
virtual void Unbind();
~VertexBufferObject();
};

最后,可执行文件可以使用工厂函数并创建类的导出方法,但不能创建特定于 dll 的方法。这可能吗?还有其他方法可以处理吗? (此外,如果您对图形 API 感兴趣并且可以发现其中的任何缺陷,那会很酷,但不是问题的重点。)

最佳答案

当然可以在 DLL 端执行此操作:您的每个实现都将在一个单独的编译单元和一个单独的 DLL,甚至一个单独的项目中。但是……

但这在DLL客户端是行不通的,因为客户端必须知道对象的定义,而ODR规则要求只有一个定义。

因此,您最好选择经过修改且更具可持续性的设计。

选项 1:使用公共(public)接口(interface)的继承

class IVertexBuffer {
public:
// Exported methods
virtual void Build(Vec2 array)=0;
virtual void Build(Vec3 array)=0;
virtual void Unbind()=0;
virtual ~IVertexBuffer(); // virtual function ==> virtual dtor !!!
};

在 openglGraphics.dll 中:

class VertexBufferGLObject : public IVertexBuffer {
private:
uint vbo;
std::vector<Vec3> arr;
public:
// Unexported methods
IDirect3DVertexBuffer9 *getVBO();

// Exported methods of the interface
void Build(Vec2 array) override;
void Build(Vec3 array) override;
void Unbind() override;
~VertexBufferObject();
};

工厂可以根据软件配置加载正确的 dll,并创建 VertexBufferGLObject ,而客户端代码只会使用多态基类。

然而,这意味着客户端代码仅使用指针和引用。如果需要复制,您需要使用 clone() 函数来避免切片的风险。

选项 2:更灵活地隐藏内部结构

您还可以使用 PIMPL idiom也称为 compilation firewall .

思路如下:

class IVertexBufferImpl;  // you need to define this only in the implementation 
class VertexBufferObject {
private:
IVertexBufferImpl *myobject;
public:
// Exported methods
virtual void Build(Vec2 array);
virtual void Build(Vec3 array);
virtual void Unbind();
virtual ~VertexBufferObject();
// + rule of 3
};

你有更多的间接层次。但是此类的实现会将调用转发给 IVertexBuffer 对象,您可以使用工厂来创建私有(private)对象,如选项 1 中所示。优点是客户端可以将 VertexBufferObject 用作​​任何其他对象(按值或按引用) ): 它在封装/隔离方面更进一步。

方案三:使用桥梁设计模式

bride design pattern旨在将抽象与其实现解耦。

它在工作方式上与选项2类似,但意图不同:目标不是隐藏实现,而是解耦,以避免两边的推导和细化:在抽象上和在实现方。

关于c++ - 在多个 DLL 中分离类实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40685149/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com