Where to delete an object created by factory?
Asked Answered
O

4

17

If I have a factory, that creates an object and returns a pointer to it, what will be a better way to delete it:

By delete call in the "user" code, or by a new DestructObject function which I should have together with the factory?

Oldline answered 11/7, 2010 at 7:2 Comment(1)
Depends on who owns the object once created. But it is never a good idea to return a pointer as that has zero ownership semantics associated with it.Dvina
C
14

In the general case, the factory might not use plain old new to allocate the object. It may use object and/or page pooling, malloc with placement new, or something even more exotic (memory mapping?). There are at least three ways to handle this that I can think of:

  1. Have the factory supply a recycle method to be called when you are done with the object.
  2. Return a smart pointer that knows how to do away with the object once no referers remain.
  3. Implement a custom delete operator in the object itself.

I hesitate to recommend one over the other, since I haven't given it enough thought in the last five minutes to proffer a definitive opinion, but I would tend to favour the last option in combination with a regular smart pointer like boost/tr1::shared_ptr.

Critchfield answered 11/7, 2010 at 7:8 Comment(5)
Beware passing around objects over DLL boundaries with shared_ptr. Use an intrusive_ptr then... I came over that issue once and that destroyed my hope that when using shared_ptr, then you are always on the safe side.Diaz
@jdehaan: The shared_ptr will invoke the custom delete which is always on the "safe side".Critchfield
@Marcelo, thanks for that precision, maybe the case I had was probably related to an old version of boost::shared_ptr under Windows with plug-in dlls that were loaded/unloaded frequently. I switched to .NET development a couple of years ago. The boost rationale regarding intrusive_ptr has become really a bit unclear: boost.org/doc/libs/1_43_0/libs/smart_ptr/intrusive_ptr.html. Not sure what are good reasons to prefer intrusive_ptr then!Diaz
@jdehaan: The issue may have been related to use of the default delete operator, which will invoke whatever underlying memory allocator is linked into the calling code. If the allocator is linked statically on either side (or simply two different allocators linked dynamically), then nasty crashes are just around the corner. Also note that the custom delete I'm referring to must be compiled into the library, so it mustn't be declared inline.Critchfield
@Marcelo, That's it! Without the default delete the code works well... Thank you so much for clarifying this.Diaz
C
1

The best way to delete it manually would be not at all.

Centimeter answered 11/7, 2010 at 7:10 Comment(1)
Sarcasm does not translate well to any recorded format. It would be best advices to avoid it and be specific rather than hiding the meaning in links. But +1 for smart pointers as a possible method.Dvina
C
1

The following code provides an opportunity not to think about who should remove the newly created object.

class FooFactory
{
public:
    static std::auto_ptr<Foo> CreateInstance();
};

// transmit ownership of created object from factory to 'a' variable
std::auto_ptr<Foo> a = FooFactory::CreateInstance();
// using the created object is not required
FooFactory::CreateInstance();
Costume answered 11/7, 2010 at 8:26 Comment(0)
B
0

The most versatile solution for this problem is to derive your class from a base class that has a virtual "killing" function. Something like this:

class IDisposable {
public:
    virtual void Release() = 0;
};

It's generally believed that polymorphic objects should have virtual destructors to support proper object cleanup. However this is incomplete, because it doesn't account for potentially different memory management of objects.

On the other hand this method doesn't require to use virtual destructors. It's now replaced by Release function that does both: invokation of the correct destructor and releasing the memory by the appropriate means.

takes care of the object destr

both: destruct

The object returned from the factory will implement this "interface".

Bandylegged answered 11/7, 2010 at 7:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.