我在嵌入式环境(Arduino / AVR ATMega328)中工作,并希望在C ++中实现Factory Method模式。但是,我正在使用的编译器(avr-gcc)不支持new
关键字。有没有办法在不使用new
的情况下实现此模式?
答案 0 :(得分:8)
由于AVR编译器基于gcc编译器,因此很可能支持new关键字。你得到的错误究竟是什么?我猜它是一个未定义函数的链接/编译器错误,即operator new。 new运算符和operator new之间存在差异,第一个用于创建对象,后者用于为对象分配内存。 new运算符为正在创建的对象类型调用operator new,然后初始化对象的v-table并调用对象的构造函数。 Reading this FAQ它表示标准库中没有定义operator new。这很容易解决,只需定义一个:
void *operator new (size_t size)
{
return some allocated memory big enough to hold size bytes
}
你也需要定义删除:
void operator delete (void *memory)
{
free the memory
}
唯一要添加的是内存管理,内存块的分配和释放。这可以简单地完成,小心不要破坏任何现有的已分配内存(代码,静态/全局数据,堆栈)。您应该定义两个符号 - 一个用于空闲内存的开始,另一个用于空闲内存的结束。您可以动态分配和释放此区域中的任何内存块。你需要自己管理这个记忆。
答案 1 :(得分:3)
如果无法在运行时实例化类,我认为这是不可能的。您所能做的就是在编译时预先分配一些对象,创建对它们的引用并在需要时返回它们。
答案 2 :(得分:3)
Factory Method的大图是对象创建,这意味着堆内存消耗。在嵌入式系统上,您受到RAM的限制,需要在考虑内存限制的情况下做出所有设计决策。 ATmega328只有2 KB RAM。我建议不要在如此狭小的空间内使用动态分配的内存。
在不详细了解您的问题的情况下,我建议静态声明该类的一些实例并以某种方式重用这些实例。这意味着您需要知道创建对象的时间和原因 - 只是重要 - 它们何时以及为何结束;那么你需要弄清楚你需要一次有多少活动,以及一次有多少活动。
!!迪安
答案 3 :(得分:1)
这样的事情怎么样?
MyClass *objp = (MyClass*)malloc(sizeof(MyClass));
*objp = MyClass(); // or any other c'tor
编辑:忘记提及,它假设MyClass有一个赋值运算符。
EDIT2:我忘记的另一件事 - 是的,有一个问题(它是C ++,总是有问题)。你必须手动为对象调用d'tor,因为你不能免费使用。
答案 4 :(得分:0)
你能做malloc吗?如果是这样,你就可以用这种方式来对象。
您想要从工厂创建的对象的性质是什么?
如果两个问题的答案都是肯定的,那么你可以静态地为你的一组不可变对象分配内存,让工厂方法返回指向相应对象的指针。
如果对这两个问题的答案都是肯定的,这将无效。另外wuth这种方法你总是有分配内存的问题。
答案 5 :(得分:0)
如果您正在使用工厂意味着您需要一些动态绑定行为,这表明您有一些虚拟功能。虽然,有可能使用malloc()为对象分配内存,但是类的vtable将无法正确设置,因此对虚函数的调用将崩溃。当需要动态绑定时,我没有看到任何方法。
答案 6 :(得分:0)
我在具有严格编码标准(我们不允许使用“新”或“删除”)的嵌入式系统中解决此问题的方法是创建所需对象的静态数组。然后使用静态指针指向已经分配的对象,存储这些返回值(使用静态变量和/或成员变量),以便以后执行各种对象。
// Class File ---------------------------------------------------
class MyObject {
public:
MyObject* getObject();
private:
const int MAX_POSSIBLE_COUNT_OF_OBJECTS = 10;
static MyObject allocatedObjects[MAX_POSSIBLE_COUNT_OF_OBJECTS];
static allocatedObjectIndex = 0;
};
// Implementation File ------------------------------------------
// Instantiate a static array of your objects.
static MyObject::allocatedObject[MAX_POSSIBLE_COUNT_OF_OBJECTS];
// Your method to return already created objects.
MyObject* MyObject::getObject() {
if (allocatedObjectIndex < (MAX_POSSIBLE_COUNT_OF_OBJECTS - 1)) {
return allocatedObjects[allocatedObjectIndex++];
} else {
// Log error if possible
return NULL;
}
}
请预先警告。这完全来自记忆,因为我在8个月内没有写过任何C ++。
另请注意:这有一个严重的缺点,就是你在编译时分配了一堆RAM。