在嵌入式系统中不使用堆的 C++ 组合
C++ composition without using the heap in embedded systems
我是 C++ 的新手,这也是我的第一个 post。我正在尝试在嵌入式系统项目中使用 C++,以便采用 OOP 方法。我正在使用 AVR crosspack 工具链(AVR G++ 编译器)
我的问题是:
根据我的阅读,堆不应该用于嵌入式系统中的动态内存分配。无论如何,在 AVR G++ 中无论如何都没有“新”的实现。我正在使用组合,从一个 USART 驱动程序(我们称之为服务)和一个记录器(单例模式,也是一个服务)开始。
据我了解,服务应该使用构造函数参数在实例化时传递它们的依赖关系,但是当我尝试以这种方式组合所需的对象时,出现以下错误:
Main/main.cpp: In function 'int main()':
Main/main.cpp:21:13: error: request for member 'log' in 'logSystem', which is of non-class type 'LogSystem(Usart)'
21 | logSystem.log("Hello");
| ^~~
make: *** [Main/main.o] Error 1
我的感觉是我将对象作为构造函数参数传递的语法是错误的,但我不确定它应该是什么,因为我能找到的所有示例都在构造函数定义中使用“new”关键字在免费商店上创建对象。有人可以帮忙吗?
代码:
在“usart.h”中:
#include <avr/io.h>
#include <util/setbaud.h>
class Usart
{
public:
// Constructor and destructor
Usart();
~Usart();
// Initialisation routine
static void const init(void);
// Utility function to transmit a string
static void const print(const char myString[]);
};
在“logger.h”中:
#include "usart.h"
class LogSystem
{
public:
LogSystem(Usart usart);
~LogSystem();
Usart usart;
static void const log(char *msg);
};
在“logger.cpp”
#include "logger.h"
LogSystem::LogSystem(Usart usart)
{
Usart usart;
usart.init();
}
LogSystem::~LogSystem()
{
}
LogSystem::log(char *msg)
{
usart.print(msg);
}
在“main.cpp”中:
#include "logger.h"
int main()
{
LogSystem logSystem(Usart usart);
while(1)
{
logSystem.log("Hello");
}
return 0;
}
[...] the heap should not be used for dynamic memory allocation in embedded systems.
视情况而定。我目前在一个具有最高安全相关要求的嵌入式项目中,我们使用 new
,但不使用 delete
。所以我们有一个堆,但不要“动态”分配,因为所有分配的对象都在运行时保留。
In any case, there is no implementation for "new" in AVR G++ anyway.
这是真的吗?我从未检查过...在能够使用 new
.
之前可能需要提供一个堆
It's my understanding that services should have their dependancies passed in on instantiation using constructor parameters, [...]
这是个好主意。 ;-) 它有助于单元测试。
对于您的语法和设计问题:这就是我编写您的来源的方式。
"usart.h":
所有方法都是非静态的,可以访问成员变量。
return 类型的 const
属性没有任何作用。您是要声明方法常量吗?然后 const
属于参数列表之后。但是,如果这样的方法更改任何成员变量,则此属性可能是错误的。
#include <avr/io.h>
#include <util/setbaud.h>
class Usart
{
public:
Usart();
~Usart();
void init(void);
void print(const char myString[]);
};
"logger.h":
只需提供并存储对 USART 的引用即可避免复制。
#include "usart.h"
class LogSystem
{
public:
LogSystem(Usart& usart);
~LogSystem();
void log(const char *msg);
private:
Usart& _usart;
};
"logger.cpp"
成员变量_usart
直接在构造函数中初始化,在执行任何语句之前。
#include "logger.h"
LogSystem::LogSystem(Usart& usart) : _usart(usart)
{
_usart.init();
}
LogSystem::~LogSystem()
{
}
void LogSystem::log(const char *msg)
{
_usart.print(msg);
}
"main.cpp":
在堆栈上提供 USART 对象,作为记录器。
#include "logger.h"
int main()
{
Usart usart;
LogSystem logSystem(usart);
while(1)
{
logSystem.log("Hello");
}
return 0;
}
单例设计模式自发明以来就被弃用了,因为它太难测试了。只需使用一个对象或限制对象工厂。
我是 C++ 的新手,这也是我的第一个 post。我正在尝试在嵌入式系统项目中使用 C++,以便采用 OOP 方法。我正在使用 AVR crosspack 工具链(AVR G++ 编译器)
我的问题是:
根据我的阅读,堆不应该用于嵌入式系统中的动态内存分配。无论如何,在 AVR G++ 中无论如何都没有“新”的实现。我正在使用组合,从一个 USART 驱动程序(我们称之为服务)和一个记录器(单例模式,也是一个服务)开始。
据我了解,服务应该使用构造函数参数在实例化时传递它们的依赖关系,但是当我尝试以这种方式组合所需的对象时,出现以下错误:
Main/main.cpp: In function 'int main()':
Main/main.cpp:21:13: error: request for member 'log' in 'logSystem', which is of non-class type 'LogSystem(Usart)'
21 | logSystem.log("Hello");
| ^~~
make: *** [Main/main.o] Error 1
我的感觉是我将对象作为构造函数参数传递的语法是错误的,但我不确定它应该是什么,因为我能找到的所有示例都在构造函数定义中使用“new”关键字在免费商店上创建对象。有人可以帮忙吗?
代码:
在“usart.h”中:
#include <avr/io.h>
#include <util/setbaud.h>
class Usart
{
public:
// Constructor and destructor
Usart();
~Usart();
// Initialisation routine
static void const init(void);
// Utility function to transmit a string
static void const print(const char myString[]);
};
在“logger.h”中:
#include "usart.h"
class LogSystem
{
public:
LogSystem(Usart usart);
~LogSystem();
Usart usart;
static void const log(char *msg);
};
在“logger.cpp”
#include "logger.h"
LogSystem::LogSystem(Usart usart)
{
Usart usart;
usart.init();
}
LogSystem::~LogSystem()
{
}
LogSystem::log(char *msg)
{
usart.print(msg);
}
在“main.cpp”中:
#include "logger.h"
int main()
{
LogSystem logSystem(Usart usart);
while(1)
{
logSystem.log("Hello");
}
return 0;
}
[...] the heap should not be used for dynamic memory allocation in embedded systems.
视情况而定。我目前在一个具有最高安全相关要求的嵌入式项目中,我们使用 new
,但不使用 delete
。所以我们有一个堆,但不要“动态”分配,因为所有分配的对象都在运行时保留。
In any case, there is no implementation for "new" in AVR G++ anyway.
这是真的吗?我从未检查过...在能够使用 new
.
It's my understanding that services should have their dependancies passed in on instantiation using constructor parameters, [...]
这是个好主意。 ;-) 它有助于单元测试。
对于您的语法和设计问题:这就是我编写您的来源的方式。
"usart.h":
所有方法都是非静态的,可以访问成员变量。
return 类型的 const
属性没有任何作用。您是要声明方法常量吗?然后 const
属于参数列表之后。但是,如果这样的方法更改任何成员变量,则此属性可能是错误的。
#include <avr/io.h>
#include <util/setbaud.h>
class Usart
{
public:
Usart();
~Usart();
void init(void);
void print(const char myString[]);
};
"logger.h":
只需提供并存储对 USART 的引用即可避免复制。
#include "usart.h"
class LogSystem
{
public:
LogSystem(Usart& usart);
~LogSystem();
void log(const char *msg);
private:
Usart& _usart;
};
"logger.cpp"
成员变量_usart
直接在构造函数中初始化,在执行任何语句之前。
#include "logger.h"
LogSystem::LogSystem(Usart& usart) : _usart(usart)
{
_usart.init();
}
LogSystem::~LogSystem()
{
}
void LogSystem::log(const char *msg)
{
_usart.print(msg);
}
"main.cpp":
在堆栈上提供 USART 对象,作为记录器。
#include "logger.h"
int main()
{
Usart usart;
LogSystem logSystem(usart);
while(1)
{
logSystem.log("Hello");
}
return 0;
}
单例设计模式自发明以来就被弃用了,因为它太难测试了。只需使用一个对象或限制对象工厂。