在跨平台代码中使用抽象类的实例

时间:2016-04-30 18:29:25

标签: c++ cross-platform abstract-class abstract

在创建跨平台多线程应用程序时考虑这种情况。

因此,当您这样做时,您可能会在某些类之间划分平台功能。例如,您需要简单的控制台来输出应用程序中的某些文本。执行此操作的可能方式是声明一些抽象类Console,然后在某个平台上需要它时,继承它并使用派生类实例。

一切都行,直到你发现某个地方需要Console实例(例如作为类成员)。您知道,如果您尝试在其他类中声明类Console的成员变量,则会出现错误,因为不允许抽象类的实例。但是你仍然需要那个类,因为你认为在编译时派生类将被实现并且它是正确的,但你不知道该类的名称,或者根据平台可能有不同的名称。

这是一个复杂的例子。

开发跨平台多线程应用程序时,需要Syncer(Synchronizer)之类的东西。它的类比是Windows API上的互斥对象。

你知道,根据平台,这个类会有所不同。但是你确实知道任何平台变体都有一些方法。例如,这些方法是lockunlock。由于您不知道如何完成这些方法,因此您将它们声明为纯虚拟下一个:

class Syncer
{
public:
    virtual void lock()=0;
    virtual void unlock()=0;
}

现在,开发一些课程,你意识到,你不需要一个,但很多这个Syncer - s。但是你不能这样做,因为这个课是抽象的。

我找到的可行解决方案是:

1)使用模板。例如:

template<class syncer>
class SyncUser
{
public:
    syncer syncInstance;
    SyncUser()
    {
        syncInstance().lock;
}

但问题是,类用户可以粘贴而不是syncer参数任何其他类。(他会不会,这不重要。他可以做到这一点)。因此,该解决方案不如预期的一般解决方案那么好。

2)使用宏。如果使用这种方式,Syncer.h的内容就像下一个:

class Syncer
{
public:
    virtual void lock()=0;
    virtual void unlock()=0;
}
#ifdef PLATFORM1
#include "platform1_sync_implement.h"
#else
#include "platform2_sync_implement.h"
#endif

"platform1_sync_implement.h"文件具有以下内容时:

#include "Syncer.h"

class SyncPlatform1 : public Syncer
{
    //Correct implementation
}

#define Syncer SyncPlatform1

现在,包含Syncer.h的任何人都会拥有已实施的版本。 但这种方式也不好,因为需要实现Sync抽象的平台列表。这对大型项目来说并不是那么好,因为你只需要声明该类并关心其他程序员可以使用它。

所以问题是:是否有更好的方法来使用&#39;实例&#39;抽象类,知道它的子类将在某处实现。

P.S。:我知道这不是这个问题的最佳名称。 P.P.S。:抱歉英语不好。

2 个答案:

答案 0 :(得分:1)

要在不同的平台上实现不同的实现,你不应该使用多态,你应该使用旧的#if __linux__,#if defined __mac__&amp;&amp;定义__darwin __,#if _WIN32等

如果您需要充分利用实际CPU,程序最终会运行,并且您希望为每个可能的CPU专门优化实现,那么这是一个不同的故事,因为您需要一些运行时机制来选择最佳实现。

答案 1 :(得分:0)

抽象类背后的想法是提供一个完成基类的点,但将来由基类的用户提供。

如果那是什么意思,那么使用抽象类。如果基类应该按原样使用,那么提供一个空例程

class BASE {
public:
    void SomethingUnusedHere() {}
};

如果用户真正做什么并且在使用类中仍然不需要,那么用户也可以这样做。

class BASE {
  :
    void Func() = 0;
  :

}

class CHILD : public BASE {
  :
    void Func() {}
  :
}

当然,如果确实需要Func,那么它应该包含正确的代码;