首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何创建跨平台类抽象?

如何创建跨平台类抽象?
EN

Software Engineering用户
提问于 2023-04-24 17:13:30
回答 1查看 103关注 0票数 -2

我一直在思考如何创建一个“面向对象的”跨平台抽象。

在C++中,类需要在其接口(即公共方法)与其实现(即私有方法和数据)之间进行一定程度的耦合。

我知道有几种设计技术/模式可以在一定程度上解决这个问题。我要用一个“互斥”作为例子。对于这些示例,我将互斥体的“接口”定义为具有以下签名的两个方法:

代码语言:javascript
复制
void lock();
void unlock();

理想情况下,我可以使用如下所示的Mutex类:

代码语言:javascript
复制
#include <Mutex.hpp>

void myFunction()
{
    Mutex m;
    m.lock();
    //...
    m.unlock();
}

class MyClass
{
//...
private:
    mutable Mutex _mutex;
};

选项1:虚拟函数

代码语言:javascript
复制
//In IMutex.hpp
class IMutex
{
public:
    virtual void lock() = 0;
    virtual void unlock() = 0;
};

//In FreeRTOSMutex.hpp
class FreeRTOSMutex : public IMutex
{
//FreeRTOS implementation here
};

//In STDMutex.hpp
class STDMutex : public IMutex
{
//Implementation using std::mutex here
};

问题是

  1. 它引入了虚拟方法调用的开销(这通常不是问题)。
  2. 更重要的是,您不能创建IMutex的实例,因此使用互斥对象要困难得多。
  3. 对于给定的编译软件/固件,只有一个互斥实现,因此所有这些开销都是完全不必要的(即不需要运行时多态)。

选项2: PIMPL

代码语言:javascript
复制
//In Mutex.hpp
class Mutex
{
public:
    void lock();
    void unlock();

private:
    class Implementation;
    std::unique_ptr<Implementation> _impl;
};

//In Mutex.cpp for FreeRTOS
class Mutex::Implementation
{
//FreeRTOS implementation here
};
void Mutex::lock()
{
    _impl->lock();
}
void Mutex::unlock()
{
    _impl->unlock();
}

这里的优点是Mutex现在是一个可以直接创建的类(例如,在堆栈上)。缺点是它必须使用堆(对嵌入式系统不友好)。它还通过指针引入了一个间接方向。因此,真正的缺点是类似于使用虚拟方法。

选项3:“C++标准库方式”

在我看来,C++标准库规范本质上是一种抽象类型。它用文字和伪码定义了什么类、函数等.应该存在于什么文件中。然后,由特定的编译器/库实现来确保在正确的位置提供正确的文件和正确的内容。

因此,对于互斥实例,代码只是

代码语言:javascript
复制
//In FreeRTOS implementation library
//In Mutex.hpp
class Mutex
{
//Implementation for FreeRTOS
};

//In STD implementation library
//In Mutex.hpp
class Mutex
{
//Implementation for std::mutex
};

然后由用户来包含和链接正确的实现。

这种方法的缺点是对Mutex的接口没有正式的(即,在代码中)描述。因此,在编写使用Mutex的代码时,它必须至少使用一些实现。

我的问题是,我是否还没有考虑其他的解决办法?

EN

回答 1

Software Engineering用户

发布于 2023-04-25 19:43:53

抽象类对于运行时更改非常有用。除非你需要热交换运行中的应用程序.操作系统?硬件?这里不需要运行时的可变性。抽象类不是工作的最佳工具,但它可以工作。然而,还有另一种方法。分离C++中的头文件和实现文件。在Mutex.hpp中定义公共接口:

代码语言:javascript
复制
class Mutex
{
public:
    void lock();
    void unlock();
}

然后创建特定于实现的版本,以满足实现标头中方法的每个平台。

In: Platform/FreeRTOS/Mutex.cpp

代码语言:javascript
复制
class Mutex
{
public:
    void lock() {
        // FreeRTOS implementation
    }

    void unlock() {
        // FreeRTOS implementation
    }
}

为每个平台创建一个子文件夹,并在每个平台中编写一个Mutex.cpp。在构建时,根据所针对的平台链接适当的.cpp文件。对于C++和C来说,这是相当标准的开销。您可以得到一个强类型的类,而无需使用虚拟方法调用的开销。决策是在编译时作出的,而不是在运行时作出的。

票数 3
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/445228

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档