在跨平台代码中使用抽象类的实例(Use instance of abstract class in cross

编程入门 行业动态 更新时间:2024-10-10 06:22:24
在跨平台代码中使用抽象类的实例(Use instance of abstract class in cross-platform code)

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

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

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

这是一个复杂的例子。

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

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

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

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

我发现的可能解决方案是:

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抽象的平台列表。 这对大型项目来说并不是那么好,因为你只需要声明该类并关心其他程序员可以使用它。

所以问题是:是否有更好的方法来使用抽象类的“实例”,知道它的子类将在某个地方实现。

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

Consider the situation, when you create cross-platform multi-thread application.

So, when you do that, you probably would divide the platform functionality between some classes. For example, you need simple console to output some text in your application. The possible way you do this is declare some abstract class Console and than, when you need it on some platform, inherit from it and use derived classes instances.

Everything is OK till you find out, that the Console instance is needed somewhere(For example as class member). You know, that if you try to declare a member variable of class Console in some other class, you would get an error, because the instances of abstract classes are not allowed. But you still do need that class, as you consider that on compilation the derived class will be implemented and it will be correct, but you don't know the name of that class, or there may be different names depending on platform.

Here is the complicated example.

When you develop cross-platform multi-thread application, you need something like Syncer(Synchronizer). The analog of it is the mutex object on Windows API.

You know that depending on platform that class would be different. But you do know that there are some methods that any platform variant will has. For example these methods are lock and unlock. As you don't know how will these methods be done, you declare them pure virtual as next:

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

And now, developing some class, you realize, that you need not one, but a lot of this Syncer-s. But you can't do that, as the class is abstract.

The possible solutions I've found are:

1) Use templates. For example:

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

But the problem is that the class user may paste instead of syncer parameter the any other class.(Would he will or not, it doesn't matter. He can do this). So that solution is not as good as the general solution is expected.

2) Use macros. If using this way, the contents of Syncer.h would be like next:

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

when the "platform1_sync_implement.h" file has the following:

#include "Syncer.h" class SyncPlatform1 : public Syncer { //Correct implementation } #define Syncer SyncPlatform1

Now, anyone included Syncer.h would have the the implemented version. But this way is also not good, as requires the list of platforms, where the Sync abstraction will be implemented. That is not so good for big projects, as you just need to declare that class and care about that other programmers could use it.

So the question is: is there a better way to use the 'instance' of abstract class, knowing that its child class would be implemented somewhere.

P.S.: I know that that is not the best name for such question. P.P.S.: Sorry for bad English.

最满意答案

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

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

To have different implementations on different platforms, you should not use polymorphism, you should rather use good old #if __linux__, #if defined __mac__ && defined __darwin__, #if _WIN32, etc.

If you need to get the most out of the actual CPU the program eventually happens to run on, and you want implementations specially optimised for each possible CPU, then that's a different story because you need some runtime mechanism to select the best implementation.

更多推荐

本文发布于:2023-08-06 10:33:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1448365.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:实例   代码   抽象类   平台   class

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!