用C++编写抽象层的简单示例

Simple example to illustrate writing an abstraction layer in C++

本文关键字:简单 抽象 C++      更新时间:2023-10-16

我对C++只有基本的知识。我正在尝试用C++实现硬件抽象层(HAL)。假设我想要实现这个名为Data的类。基于该平台,数据可以有线或无线发送。

class Data() {
public Data() {
//create random data
}
public sendData() {
// send data
}
public platform_action1() {
// do some platform specific action
}

}

// My HAL
int HAL() {
Data myData;
myData.platform_action1();
myData.sendData();
return 0;
}

现在,如果我有两个有线和无线平台,我该如何扩展这个类并组织我的文件,以使HAL()保持不变。

此外,我不希望动态绑定,即使用关键字"virtual"。在我的情况下,该平台在编译时是已知的。

//我不想这样做:)。。。

int HAL() {
Data* data = new WiredData();
data.sendData();
data = new WirelessData();
data.sendData();
}

在我的情况下,该平台在编译时是已知的。

来自C世界,这是一项简单的任务,就像填充特定于平台的函数指针一样。

以Boost C++API中的"thread"类为例。该类通过基于平台调用Windows线程API或Linux线程API来自动生成线程。通过这种方式,我的HAL是真正独立于平台的。

  • 谢谢Kris

这更像是一个设计问题,而不是一个实际的C++问题,但您要查找的术语是polymorphism。您可以使用Data类并创建两个从中继承WiredData和`WirelessData的类,这将使您能够执行以下操作:

Data data1 = new WiredData();
Data data2 = new WirelessData();
data1.sendData();
data2.sendData();

当您在data1和data2对象上调用sendData()时,多态性就发挥了作用,编译器将为每个特定的子类型调用sendData()方法,即使它们被声明为Data类型

来自C世界,这是一项简单的任务,就像填充特定于平台的函数指针一样。

这在C++中几乎是一样的。您可以使Data类的sendData()函数virtual(在签名前面加上virtual关键字),然后派生指定适当sendData()功能的Wired和Wireless实现类。然后,您可以使用某种if语句来决定使用哪一个,并根据需要为WiredWireless对象保留一个Data*变量。。。当您调用pointer->sendData()时,它将调用相应的实现。这一切都是非常基本的——你应该在网上做一些C++入门教程,或者找一本书。还有其他堆叠式问题列出了推荐的培训材料。

编辑:根据您在下面的评论中的请求编写大纲。

class Wrapper
{
Data* p_;
public:
void sendData()
{
if (not p_)
p_ = ... ? new Wired() : new Wireless();
p_->sendData();
}
}

为什么不将更改的成员的定义放入名为:-的文件中

Data_Windows.cppData_Unix.cpp(例如),然后使用您的构建系统在该平台上的构建中只包含相关事件文件?还是我错过了什么。。。?

Can we do this using PIMPL(Private Implementation) approach? This is what I am thinking ...
// In Data.h
class PlatformDataProcess;                    // forward declaration of Pimpl
 
class Data
{
public:
   Data (const IPC& ipc); // process IPC
   ~Data();
 
   Data( const Data &rhs );   // undefined for simplicity
   Data& operator=( Data );
 
   void  process_ipc();
 
private:
   PlatformDataProcess *pimpl_;              // the Pimpl
};
// In Wired.cpp
#include "Data.h"
 
class PlatformDataProcess
{
public:
   void SendData()  {// send data on wired}
 
};

// In Data.cpp
 
Data::Data()  :  pimpl_( new PlatformDataProcess() )
{
}
 
Data::~Data()
{
   delete  pimpl_;
}
 
void   Data::SendData()
{
   pimpl_->SendData();      // do some private work   
}
int HAL() {
// receive IPC
Data* data = new Data(ipc);
data->SendData();
}
So all the user needs to do is supply the platform specific file like wired.cpp .