当然,我知道最好的答案是"不要编写自己的跨平台代码,有人已经完成了你需要的东西",但我这样做是为了一个业余爱好/学习练习而不是任何付费容量.基本上,我正在用C++编写一个小型的控制台应用程序,我想让它跨平台,处理文件,套接字和线程等事情.OOP似乎是处理这个问题的一种很好的方法,但我还没有找到一个很好的模式来编写共享相同界面跨平台的类.
简单的方法是只计划一些元接口,在整个程序的其余部分使用它,然后根据平台编译不同文件的同一个类,但我觉得必须有一个更优雅的更好的方法; 至少,一些不会混淆IntelliSense及其同类产品的东西会很好.
我已经看了wxWidgets源代码中的一些较小的类,他们使用的方法使用保存类的私有成员,例如
class Foo
{
public:
Foo();
void Bar();
private:
FooData data;
};
Run Code Online (Sandbox Code Playgroud)
然后,您可以通过根据平台选择不同的实现文件来编译它.这种方法对我来说似乎很笨重.
我考虑的另一种方法是编写一个接口,并根据平台交换从该接口继承的类.像这样的东西:
class Foo
{
public:
virtual ~Foo() {};
virtual void Bar() = 0;
};
class Win32Foo
{
public:
Win32Foo();
~Win32Foo();
void Bar();
};
Run Code Online (Sandbox Code Playgroud)
当然这种搞砸了实际的实例化,因为你不知道创建一个对象的实现,但是可以通过使用一个函数来解决
Foo* CreateFoo();
Run Code Online (Sandbox Code Playgroud)
并根据您正在运行的平台改变功能的实现.我也不是这方面的忠实粉丝,因为它仍然看起来很笨拙,用一堆实例化方法乱丢代码(这也与创建非跨平台对象的方法不一致).
这两种方法中的哪一种更好?有没有更好的办法?
编辑:为了澄清,我的问题不是"你如何编写跨平台的C++?" 相反,它是"使用C++中的类抽象跨平台代码的最佳方法是什么,同时尽可能保留类型系统的好处?"
这可能看起来有点疯狂,但这是我正在考虑作为更大的库的一部分的方法,如果我可以合理地确定它不会导致奇怪的行为.
该方法:
使用SynchronizationContext
调度到线程池的异步用户代码运行.用户代码看起来像:
async void DoSomething()
{
int someState = 2;
await DoSomethingAsync();
someState = 4;
await DoSomethingElseAsync();
// someState guaranteed to be 4?
}
Run Code Online (Sandbox Code Playgroud)
我不确定访问someState
是否是线程安全的.虽然代码将在一个"线程"中运行,使得操作实际上是完全有序的,但它仍然可以分布在引擎盖下的多个线程中.如果我的理解是正确的,那么在x86上排序应该是安全的,并且因为变量不是共享的,所以我不需要担心编译器优化等等.
更重要的是,我担心这是否会在ECMA或CLR内存模型下保证线程安全.
我很确定在执行排队的工作之前我需要插入一个内存屏障,但我对这里的推理并不完全有信心(或者这种方法可能由于完全不同的原因而不可行).