Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在没有默认构造函数和堆使用的情况下初始化对象?_C++_Embedded - Fatal编程技术网

C++ 如何在没有默认构造函数和堆使用的情况下初始化对象?

C++ 如何在没有默认构造函数和堆使用的情况下初始化对象?,c++,embedded,C++,Embedded,在编写没有MMU的嵌入式系统时,我不应该使用heap(因为内存碎片问题) 部分软件用C语言编写(驱动程序),逻辑在C++子集中编写,无需动态分配内存。 由于单元测试,默认构造函数被删除。相反,有一个单参数构造函数引用驱动程序函数指针的结构 driver.h:(纯C模块) #pragma一次 bool Init(); uint32_t ReadMeasurement(); 模块.HPP:< /St>(C++部分) 类模块{ 公众: DriverApi结构{ 无效(*Init)(); uint3

在编写没有MMU的嵌入式系统时,我不应该使用heap(因为内存碎片问题)

部分软件用C语言编写(驱动程序),逻辑在C++子集中编写,无需动态分配内存。 由于单元测试,默认构造函数被删除。相反,有一个单参数构造函数引用驱动程序函数指针的结构

driver.h:(纯C模块)

#pragma一次
bool Init();
uint32_t ReadMeasurement();

<强>模块.HPP:< /St>(C++部分)

类模块{
公众:
DriverApi结构{
无效(*Init)();
uint32_t(*ReadData)();
};
模块()=删除;
显式模块(DriverApi和aDriverApi);
私人:
DriverApi&mDriverApi;
};
模块管理器:

模块管理器。hpp:

类模块管理器{
//  (...)
私人:
Module::DriverApi Module_1;//我不能用这种方式声明它
Module::DriverApi Module_2;//因为缺少默认构造函数。
模块::DriverApi模块_3;
等
};
如何在不使用堆的情况下初始化
模块1
模块2
模块3
?和
n
参数构造函数

我知道的选项:

  • 它看起来很容易使用
    std::shared_ptr
    ,但是
    std::make_shared
    使用堆
  • 我可以离开默认构造函数,然后调用Init(Module::DriverApi*aDriverApi)之类的函数,但这“违反”了RAII

是否有其他方法可以创建“优雅”的嵌入式安全初始化?

使用默认构造函数或使用命名参数编写构造函数。如果需要将成员初始化为非零值,但由于构造函数的参数太少而无法访问这些值,则构造函数的设计不正确

由于单元测试,默认构造函数被删除

测试应该是为了使产品更好——如果它们做的相反,就把它们扔掉

通常,任何嵌入式系统都有一组固定的驱动程序。所以通常情况下,将它们作为非静态成员是没有意义的。为每个硬件外围设备提供一个驱动程序类是有意义的。然后为目标上存在的该硬件的每个实例创建一个
静态
实例。您不需要涵盖永远不会出现的硬件,也不需要在运行时动态更改硬件。事实上,它的很大一部分应该是常量,并存储在闪存中

RAII在单核、单进程嵌入式系统上的使用有限,因为您的程序需要确定性,并且它拥有MCU上的所有资源。您通常不需要释放任何东西,您所需要的只是分配产品所需的内存


保持简单。不要发明毫无意义的抽象层。

我只是把代码放在IDE中,然后编译。 我可以在您的计划中确定的内容:

  • 如果您尝试分配
    bool Init()
    void(*Init)(
    ,请更改返回类型

  • 定义用户定义的构造函数时,默认构造函数已被隐式删除。缺少的是必须初始化成员。 尝试显式模块(DriverApi和aDriverApi):mDriverApi{aDriverApi}{}

     class Module {
     public:
         struct DriverApi {
             void (*Init)();
             uint32_t (*ReadData)();
         };
    
         Module() = delete;
         explicit Module(DriverApi &aDriverApi):mDriverApi{aDriverApi}{}
    
     private:
         DriverApi& mDriverApi;
     };
    
    
     void fun(){
         std::cout<<"This is fun\n";
     }
    
     int main(){
    
         Module::DriverApi module_1; // I can't declare this in this way because of lack of default constructor.
    
         module_1.Init = fun;
         module_1.Init();
    
         Module m{module_1};
    
         return 0;
     }
    
    类模块{
    公众:
    DriverApi结构{
    无效(*Init)();
    uint32_t(*ReadData)();
    };
    模块()=删除;
    显式模块(DriverApi和aDriverApi):mDriverApi{aDriverApi}{}
    私人:
    DriverApi&mDriverApi;
    };
    虚无乐趣(){
    
    std::coutFirst定义一个
    DriveApi
    对象,然后用它定义
    Module
    对象?可以在任何范围内完成。我不确定我是否理解这个问题。
    Module::DriverAPI d;//使用d执行操作;模块m(d);
    ?如果你的类没有默认构造函数,你需要调用另一个构造函数。你能解释一下为什么你认为你需要堆吗?(不清楚你想解决什么问题,更不用说你想解决什么问题了)将
    mDriverApi
    作为引用似乎有些奇怪。说来没错,但这确实让我想知道为什么。关于更新的编辑。
    Module::DriverApi Module_1;
    很好。这是一个类成员声明,而不是实际的定义。这里没有初始化任何内容。它在
    ModuleManager
    的构造函数中如果你真的初始化了成员。