我可以在不使用new的情况下在C ++中实现Factory Method模式吗?

时间:2009-06-23 08:21:07

标签: c++ embedded avr avr-gcc factory-method

我在嵌入式环境(Arduino / AVR ATMega328)中工作,并希望在C ++中实现Factory Method模式。但是,我正在使用的编译器(avr-gcc)不支持new关键字。有没有办法在不使用new的情况下实现此模式?

7 个答案:

答案 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。