Can I implement the Factory Method pattern in C++

2019-01-23 19:31发布

I'm working in an embedded environment (Arduino/AVR ATMega328) and want to implement the Factory Method pattern in C++. However, the compiler I'm using (avr-gcc) doesn't support the new keyword. Is there a way of implementing this pattern without using new?

7条回答
可以哭但决不认输i
2楼-- · 2019-01-23 20:11

Can you do malloc? If so you can malloc your object that way.

Also what is the nature of your objects that you want to create from the Factory?

  • Are they imutable?
  • Is the factory only intended to produce a limited set of objects that can be known at compile time?

If the answer is yes to both questions, you can statically allocate the memory for your set of immutable objects and let the factory method return pointers to the appropriate object.

This will not work if the answer is no to either question. Also wuth this approach you have the problem of always having that memory allocated.

查看更多
The star\"
3楼-- · 2019-01-23 20:12

If there is no way to instantiate a class at runtime, I suppose this isn't possible. All you could do is to pre-allocate some objects at compile time, create references to them and return them when needed.

查看更多
Animai°情兽
4楼-- · 2019-01-23 20:12

What about something like this?

MyClass *objp = (MyClass*)malloc(sizeof(MyClass));
*objp = MyClass();  // or any other c'tor

EDIT: Forgot to mention, it assumes MyClass has an assignment operator.

EDIT2: Another thing I forgot - yes, there's a gotcha (it's C++, there are always gotchas). You'll have to call the d'tor manually for the object, since you can't use free.

查看更多
Fickle 薄情
5楼-- · 2019-01-23 20:15

Since the AVR compiler is based on the gcc compiler, it is very likely to support the new keyword. What exactly is the error you're getting. I'm guessing it's a link/compiler error along the lines of an undefined function, namely, operator new. There is a difference between the new operator and operator new, the first is used to create objects and the latter is used to allocate memory for objects. The new operator calls operator new for the type of object being created, then initialises the object's v-table and calls the object's constructors. Reading this FAQ it says that operator new is not defined in the standard libraries. This is easy to fix, just define one:

void *operator new (size_t size)
{
  return some allocated memory big enough to hold size bytes
}

and you'll need to define a delete as well:

void operator delete (void *memory)
{
   free the memory
}

The only thing to add is the memory management, the allocation and freeing of blocks of memory. This can be done trivially, being careful not to clobber any existing allocated memory (the code, static / global data, the stack). You should have two symbols defined - one for the start of free memory and one for the end of the free memory. You can dynamically allocate and free any chunk of memory in this region. You will need to manage this memory yourself.

查看更多
虎瘦雄心在
6楼-- · 2019-01-23 20:20

The big picture of the Factory Method is object creation, which means heap memory consumption. On an embedded system, you are constrained by RAM and need to make all your design decisions with your memory limits in mind. The ATmega328 only has 2 KB RAM. I would recommend against using dynamically allocated memory in such a tight space.

Without knowing your problem in more detail, I would recommend statically declaring a handful of instances of the class and re-use those instances in some fashion. This means you need to know when and why your objects are created and--JUST AS IMPORTANT--when and why they end; then you need to figure out how many you need to have active at one time and how many it is possible to have active at one time.

!!Dean

查看更多
时光不老,我们不散
7楼-- · 2019-01-23 20:20

If you are using factory means that you want some dynamic binding behavior which indicates that you have some virtual functions. Although, it may be possible to allocate the memory for the object using malloc() the vtable of the class will not be setup properly and hence the call to virtual functions will crash. I don't see any way of doing this when dynamic binding is required.

查看更多
登录 后发表回答