C++ C++;DLL:不公开整个类
如何“隐藏”类的某些部分,以便使用库的人不必包含我的类中使用的所有类型的头。Ie以下面的MainWindow类为例,当在静态/动态库中编译时,使用库的人不必包括windows。h、Ie HWND、CRITICAL_SECTION、LRESULT等不必定义 我知道我可以将它分为两个类,一个是只包含公共接口的抽象类,另一个是包含需要windows.h的成员的隐藏实现类 这里的问题是visible类不能再自己创建,需要一个额外的创建函数(例如CreateMainWindow)。在这种情况下,这很好,因为很可能只需要在堆上创建一个实例,但对于其他类则不需要C++ C++;DLL:不公开整个类,c++,C++,如何“隐藏”类的某些部分,以便使用库的人不必包含我的类中使用的所有类型的头。Ie以下面的MainWindow类为例,当在静态/动态库中编译时,使用库的人不必包括windows。h、Ie HWND、CRITICAL_SECTION、LRESULT等不必定义 我知道我可以将它分为两个类,一个是只包含公共接口的抽象类,另一个是包含需要windows.h的成员的隐藏实现类 这里的问题是visible类不能再自己创建,需要一个额外的创建函数(例如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);
};
这本书可能会给你一些想法:
大型C++软件设计< /P>
正如你在问题中提到的,使用抽象接口是你最好的选择。DLL应该具有用于创建/销毁具体类实例的工厂方法。我没有完全理解你关于这一缺点的观点。你可以使用所谓的“柴郡猫”、“字母/信封”或“pimpl”技术隐藏类的一部分(对于同一种技术,它们都是不同的名称):
最好的方法可能是你在第二段中提到的抽象类(但我没能理解你的最后一句话,你(试图/未能)解释你的反论点是什么)。不管怎样,你有两种选择:
第三个选项(非常可怕的黑客行为,很有趣)是在你向用户公开的对象中创建一个大字节数组,然后使用“就地”新对象初始化该数组中的真实对象。请不要这样做。我要去用肥皂洗脑。正如前面所说的,你要用皮条客。我已经做到了,而且效果非常好。它对库的用户是完全透明的。注意,对于pimpl习惯用法,不需要特殊的工厂方法-ManWindow的构造函数(在本例中)应该负责构造ImplementationDetails对象。如果OP希望避免抽象类和工厂方法,那么客户机不需要处理这些。我认为他的意思是,由工厂方法创建的任何抽象类
都不能被用户子类化,或者
不能让该类的对象成为另一个类的成员,或者
你不能把它们放在标准集装箱船上。我不确定Fire Lancer是否关心子类化,特别是考虑到类已经在DLL中编译的事实。您仍然可以拥有具有指向隐藏类实例的指针的成员的对象。
class MainWindow
{
private:
//opaque data
class ImplementationDetails;
ImplementationDetails* m_data;
public:
... declare your public methods here ...
}