首页 > 解决方案 > 没有堆的 c++ 多态性

问题描述

我从 C++ 嵌入式开发开始,并正在寻找在不使用堆的情况下实现工厂模式。我发现这篇文章https://barrgroup.com/embedded-systems/how-to/polymorphism-no-heap-memory展示了如何在没有堆的情况下进行多态性。所以我可以用它来实现工厂模式。

读完这篇文章后,我意识到我可以只使用“placement new”来实现同样的事情,我的代码可以工作。

#include <iostream> 
#include <new>
#include <assert.h>

using namespace std; 

enum VehicleType { 
    VT_TwoWheeler, VT_ThreeWheeler
}; 

char buff[20];

class Vehicle { 
public: 
    virtual void printVehicle()=0; 
}; 

class TwoWheeler : public Vehicle { 
public: 
    TwoWheeler() {
        assert(sizeof(*this) <= sizeof(buff));  
    }
    void printVehicle() { 
        cout << "I am two wheeler" << endl; 
    } 
}; 
class ThreeWheeler : public Vehicle { 
public: 
    ThreeWheeler() {
        assert(sizeof(*this) <= sizeof(buff));  
    }
    void printVehicle() { 
        cout << "I am three wheeler" << endl; 
    } 
}; 

Vehicle *v1ptr;

// Driver program 
int main() { 
    VehicleType type = VT_ThreeWheeler; 
    if (type == VT_TwoWheeler) 
        v1ptr = new(buff) TwoWheeler;
    else if (type == VT_ThreeWheeler) 
        v1ptr = new(buff) ThreeWheeler;
    v1ptr->printVehicle(); 
    return 0; 
} 

它正确打印:我是三轮车

有人看到这个实现有什么陷阱吗?谢谢

标签: c++embedded

解决方案


有人看到这个实现有什么陷阱吗?

您未能对齐对象的缓冲区。的对齐要求char仅为 1,这对于大多数类型来说是不够的。您需要使用alignas来指定更严格的对齐方式,并且应该alignof在检查旁边添加验证sizeof

实现类似的结构化方法可能是使用std::variant

std::variant<TwoWheeler, ThreeWheeler> vehicle;

if (type == VT_TwoWheeler) 
    v1ptr = &vehicle.emplace<TwoWheeler>();
else if (type == VT_ThreeWheeler) 
    v1ptr = &vehicle.emplace<ThreeWheeler>();

额外建议:您可以在编译时使用static_assert.


推荐阅读