如何创建一个库,没有用户必须包含我的库使用的每个库的标题? [英] How to make a library without users having to include the headers for each library my library uses?

查看:66
本文介绍了如何创建一个库,没有用户必须包含我的库使用的每个库的标题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经写了一段时间了,但是我从来没有弄清楚如何制作它所以用户不必包含我正在使用的所有依赖项的标题我的图书馆。问题是我的类需要存储来自各种依赖项的指针和数据类型,这些依赖项必须在使用前定义。



我试过定义基本的抽象版本这些数据类型在使用之前适用于大多数类型,但有一些会给我带来类似重新定义或类似错误的错误。我还尝试使用#ifdef来仅在我编译库时在头文件中定义这些变量,但是当我尝试使用我的库而没有在头文件中定义的那些变量时,我会得到未定义的行为,其中随机的东西只是错误。那么我如何在我的库中使用第三方库而不需要包含它们的标题?



在我的库标题中说我有这个类:



I''ve been writing a library for awhile now but I''ve never been able to figure out how to make it so users don''t have to include the headers for all the dependencies I''m using in my library. The problem is that my classes need to store pointers and data types from various dependencies which have to be defined before use.

I''ve tried defining basic abstract versions of these data types before use which works for most types but there are a few that give me errors like type redefinition or what ever. I also tried to use an #ifdef to only define these variables within the header when I''m compiling my library but when I try to use my library without those variables defined in the header I get undefined behavior where random stuff just bugs out. So how the heck do I use third party libraries inside my library without needing to include their headers?

Say in my library header I have this class:

class __declspec( dllexport ) Myclass
{
public:
SDL_GLContext Context;
};





如果任何人要包含我的标题,他们首先需要包含SDL。如何在我的类中存储上下文而不需要我的库的用户包含SDL?



For anyone to include my header they would first need to include SDL. How can I store the context in my class without needing users of my library to include SDL?

推荐答案

有两种方法可以处理第三方包含:



a)将第三方标题的#include放在你自己的标题中



b)不要嵌入第三方的完整对象,但只是一个指针。在您的情况下看起来像:



There are two methods to handle third-party includes:

a) put the #include of the third party header inside your own header

b) don''t embed a full object of the third party, but just a pointer. In your case that would look like:

class SDL_GLContext;

class __declspec( dllexport ) Myclass
{
public:
    SDL_GLContext* pContext;
};





然后在Myclass构造函数中分配对象。这样,你只需要预先声明第三方类(上面代码中的第一行)。



还有两种技术值得一提。



- 在Microsoft平台上,您可以在库代码中使用#pragma指令,以便为库的用户保存将库放在链接器输入列表上的工作。例如



Then allocate the object inside your Myclass constructor. That way, you only need to make an advance declaration of the third-party class (first line in the code above).

There are two more techniques worth mentioning.

- on the Microsoft platform you can use #pragma directives inside your library code to save the users of your library the work of putting your library on the linker input list. For example

#pragma comment (lib, "MyLib.lib")





- 使用所谓的PIMPL技术(代表指向指向实现的指针)。这意味着:在类中声明一个数据成员,这是指向实现类的指针。然后,在.cpp文件中,声明一个包含所需成员数据的实现类。例如:





- use the so-called PIMPL technique (stands for pointer to pointer-to-implementation). This means: Declare just a single data member inside your class, which is a pointer to an implementation class. Then, in the .cpp file your declare an implementation class with all the member data you need. For example:

// in your .h file
class MyClassImpl;

class MyClass
{
public:
    // just declare those functions the external user is
    // allowed to see

private:
    MyClassImpl* m_pThis;
};

// in your .cpp file
class MyClassImpl
{
public:
    // here goes the implementation declaration of all the stuff
    // that should be hidded from the user
};

MyClass::MyClass()
{
     m_pThis = new MyClassImpl;
}
MyClass::~MyClass()
{
    delete m_pThis;
}





这是一个很好的技术来曝晒你的课程,让外表只知道你班级的最低限度。特别是:类的外部大小始终保持不变(只是指针的大小)。当您的类是库的一部分并且用户在他自己的代码中分配您的类的对象时,这非常有用。然后,您可以向您的实现添加成员,而无需用户重新编译其整个代码。



This is a nice technique to insolate your class and let the exterior only know the bare minimum about your class. Particularly: The external size of the class always stays the same (just the size of the pointer). That is very useful when your class is part of a library and the user allocates objects of your class in his own code. You may then add members to your implementation without having the user to recompile his entire code.


这篇关于如何创建一个库,没有用户必须包含我的库使用的每个库的标题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆