C ++ DLL:不暴露整个类

时间:2009-01-08 18:54:18

标签: c++

如何“隐藏”类的某些部分,以便使用该库的任何人都不必包含我班级中使用的所有类型的标题。即下面的MainWindow类,我可以拥有它,所以当在静态/动态库中编译时,无论谁使用libary都不必包含windows.h,即HWND,CRITICAL_SECTION,LRESULT等不必定义

我知道我可以把它分成两个类,一个只有公共接口的抽象类,一个隐藏的实现类,它包含需要windows.h的成员。

这里的问题是无法再创建可见类,并且需要额外的创建函数(例如CreateMainWindow)。在这种情况下这很好,因为最有可能的是只需要在堆上创建一个实例,但对于其他类,这不是。

class MainWindow
{
    HWND hwnd;
    int width, height;
    std::string caption;
    bool started,exited;
    bool closeRequest;

    unsigned loopThread;
    CRITICAL_SECTION inputLock;

    Input *input;
public:
    static void init_type();
    Py::Object getattr(const char *name);

    MainWindow(int width, int height, std::string caption);
    ~MainWindow();

    bool CloseRequest(const Py::Tuple &args);
    bool CloseRequestReset(const Py::Tuple &args);

    HWND GetHwnd();

    int GetWidth();
    int GetHeight();

    Input* GetInput();
protected:
    unsigned static __stdcall loopThreadWrap(void *arg);
    unsigned LoopThreadMain();

    LRESULT WndProc(UINT msg, WPARAM wParam, LPARAM lParam);
    LRESULT static CALLBACK WndProcWrapper(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
};

5 个答案:

答案 0 :(得分:7)

您可以使用所谓的“cheshire cat”,“letter / envelope”或“pimpl”技术隐藏某个类的部分(对于相同的技术,它们都是不同的名称):

class MainWindow
{
private:
    //opaque data
    class ImplementationDetails;
    ImplementationDetails* m_data;
public:
    ... declare your public methods here ...
}

最好的方法可能是你的第2段中提到的抽象类(但是我​​没理解你的最后一句话,你(尝试/未能)解释你的反驳论点是什么。)

答案 1 :(得分:4)

正如您在问题中提到的,使用抽象界面是您的最佳选择。您的DLL应具有用于创建/销毁具体类实例的工厂方法。我对这个问题的不利之处并不十分清楚。

答案 2 :(得分:1)

无论如何,您有两种选择:

  1. 让库用户的编译器找出数据所需的内存大小 - 然后编译器可以将它放在堆栈上
  2. 或者为库用户分配堆上的数据,以便用户的编译器不需要知道数据有多大。
  3. 无论是通过pimpl公开(2)还是MyAbstractObject * o = createMyObject()都没有太大的不同。

    第三个选项(黑客太可怕,很有趣)在您向用户公开的对象中创建一个大字节数组,并使用“就地”新建初始化该数组中的真实对象。请不要这样做。我会用肥皂洗我的大脑。

答案 3 :(得分:0)

这本书可能会给你一些想法:

http://www.amazon.com/Large-Scale-Software-Addison-Wesley-Professional-Computing/dp/0201633620

大型C ++软件设计

作者John Lakos

答案 4 :(得分:0)

如前所述,你想要使用pimpl。我做到了,效果非常好。它对您的图书馆用户完全透明。