我一直在思考如何创建一个“面向对象的”跨平台抽象。
在C++中,类需要在其接口(即公共方法)与其实现(即私有方法和数据)之间进行一定程度的耦合。
我知道有几种设计技术/模式可以在一定程度上解决这个问题。我要用一个“互斥”作为例子。对于这些示例,我将互斥体的“接口”定义为具有以下签名的两个方法:
void lock();
void unlock();理想情况下,我可以使用如下所示的Mutex类:
#include <Mutex.hpp>
void myFunction()
{
Mutex m;
m.lock();
//...
m.unlock();
}
class MyClass
{
//...
private:
mutable Mutex _mutex;
};//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
};问题是
//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现在是一个可以直接创建的类(例如,在堆栈上)。缺点是它必须使用堆(对嵌入式系统不友好)。它还通过指针引入了一个间接方向。因此,真正的缺点是类似于使用虚拟方法。
在我看来,C++标准库规范本质上是一种抽象类型。它用文字和伪码定义了什么类、函数等.应该存在于什么文件中。然后,由特定的编译器/库实现来确保在正确的位置提供正确的文件和正确的内容。
因此,对于互斥实例,代码只是
//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的代码时,它必须至少使用一些实现。
我的问题是,我是否还没有考虑其他的解决办法?
发布于 2023-04-25 19:43:53
抽象类对于运行时更改非常有用。除非你需要热交换运行中的应用程序.操作系统?硬件?这里不需要运行时的可变性。抽象类不是工作的最佳工具,但它可以工作。然而,还有另一种方法。分离C++中的头文件和实现文件。在Mutex.hpp中定义公共接口:
class Mutex
{
public:
void lock();
void unlock();
}然后创建特定于实现的版本,以满足实现标头中方法的每个平台。
In: Platform/FreeRTOS/Mutex.cpp
class Mutex
{
public:
void lock() {
// FreeRTOS implementation
}
void unlock() {
// FreeRTOS implementation
}
}为每个平台创建一个子文件夹,并在每个平台中编写一个Mutex.cpp。在构建时,根据所针对的平台链接适当的.cpp文件。对于C++和C来说,这是相当标准的开销。您可以得到一个强类型的类,而无需使用虚拟方法调用的开销。决策是在编译时作出的,而不是在运行时作出的。
https://softwareengineering.stackexchange.com/questions/445228
复制相似问题