有更多方法可以解决这个问题 - 每种方法都有其优点和缺点。
1.) 使用宏#ifdef、#endif
// Note: not sure if "WINDOWS" or "WIN32" or something else is defined on Windows
#ifdef WINDOWS
#include <window.h>
#else
// etc.
#endif
class MyClass
{
public:
// Public interface...
private:
#ifdef WINDOWS
HWND m_myHandle;
#else
// etc.
#endif
};
优点:
缺点:
- 更糟糕的可读性。对于许多平台,它可能会变得非常混乱。
- 包括特定于平台的包含可能会破坏某些内容。windows.h 定义了许多具有正常名称的宏。
2.)正如已经写过的那样,您可以使用多态性:
// IMyClass.h for user of your class:
class IMyClass
{
public:
virtual ~IMyClass() {}
virtual void doSomething() = 0;
};
// MyClassWindows.h is implementation for one platform
#include <windows.h>
#include "IMyClass.h"
class MyClassWindows : public IMyClass
{
public:
MyClassWindows();
virtual void doSomething();
private:
HWND m_myHandle;
};
// MyClassWindows.cpp implements methods for MyClassWindows
优点:
缺点:
- 用户不能直接创建您的类的实例(尤其是不在堆栈上)。
- 您必须提供特殊的创建函数:例如 declare IMyClass* createMyClass(); 并在 MyClassWindows.cpp 和其他平台特定文件中定义它。在那种情况下(好吧,实际上在整个多态情况下),您还应该定义破坏实例的函数 - 为了保持成语“谁创建它也应该破坏”。
- 由于虚拟方法而几乎没有减速(在这些日子里,除了非常非常特殊的情况外几乎完全无关紧要)。
- 注意:由于 RAM 碎片问题,在内存有限的平台上分配可能会出现问题。在这种情况下,可以通过为您的对象使用某种内存池来解决它。
3.) PIMPL 成语。
// MyClass.h
class MyClass
{
public:
MyClass();
void doSomething();
private:
struct MyClassImplementation;
MyClassImplementation *m_impl;
}
// MyClassWindows.h
#include <windows.h>
#include "MyClass.h"
struct MyClassImplementation
{
HWND m_myHandle;
void doSomething();
}
在这种情况下,MyClassImplementation 保留所有需要的(至少是特定于平台的)数据并实现所需的(同样是特定于平台的)。在 MyClass.cpp 中,您包含特定于平台的实现(方法可以是内联的),在构造函数中(或者稍后,如果您愿意 - 请注意)您分配实现,在析构函数中您将销毁它。
优点:
- 用户可以创建您的类的实例(包括在堆栈上)(不用担心未/删除的指针)。
- 您不需要在 MyClass.h 中包含特定于平台的标头。
- 您可以简单地添加引用计数器并实现数据共享和/或写时复制,即使它保留大量数据,也可以轻松地将您的类用作返回值。
缺点:
- 您必须分配实现对象。对象池可以提供帮助。
- 当调用一个方法时,两个被调用,一个指针解引用。不过,今天应该没有问题。
4.) 定义一个中性类型,它足够大以保存您的数据。例如 long long int。
// MyClass.h
class MyClass
{
public:
MyClass();
void doSomething();
private:
typedef unsigned long long int MyData;
MyData m_data;
};
在实现中(例如 MyClassWindows.cpp),您总是需要在 MyClass::MyData 和存储的实际数据之间进行转换(重新解释转换)。
优点:
- 与第一种方式一样快,但您避免使用宏。
- 如果不需要,避免分配。
- 避免多个方法调用。
- 避免在 MyClass.h 中包含特定于平台的标头。
缺点:
- 您必须绝对 110% 确定 MyClass::MyData 的大小始终至少与存储的数据相同。
- 如果不同的平台存储不同大小的数据,那么除非您使用宏,否则您会占用空间(如果您使用一些项目,没关系,但有数百万个项目......)。在这种情况下,它不会那么混乱。
- 这是处理数据的低级工作 - 不安全,而不是 OOP。但是快。
因此,请使用最适合您的问题的那个……以及您的个性:3,因为就当今的力量而言,所有四个在速度和空间方面都或多或少相对相等。