What is the preferred way to implement a factory method in C++?
A newbie question: I have a hierarchy of classes with some virtual functions and I am trying to implement a factory method, but I am not sure what is the best way:
- Return a raw pointer from the factory method and wrap it into a smart pointer in the calling method
- Return a smart pointer from the factory
- Return a proper object from the factory (but is it going to copy the derived class correctly?) and assign it to a local object in the calling method
- Return a reference from the factory (but how to create the object in the factory method without a memory leak?)
I 开发者_如何学JAVAwould be grateful for an example of a factory method and a minimal client, which is effective and doesn't leak memory.
My background is C# and Java, so I am a bit lost with memory management in C++ atm.
Options 3 and 4 are out from the start because they simply don’t work: 3 slices the object, 4 creates memory leaks or invalid references.
From the other two methods, I strongly prefer 2: return a smart pointer. In fact, strive to avoid raw pointers completely, if possible. Unfortunately, C++ makes this a lot to write (and this is not a trivial objection! Anybody who has ever written object-oriented code in C++ and has used smart pointers throughout shares my pain) – but the alternative is even more pain.
Of course, there is alternative 5: use raw pointers and a garbage collector.
well my taste go to returning a smart pointer. here is a link to an example Abstract factory that returns a smart pointer.
my2c
I prefer method 1 because it's more flexible. However, whether you return the raw pointer or the smart pointer is really just a matter of object usage. For example, you might want to return a raw pointer because you know that the object will sometimes be used once and immediately deleted in the same code block. In that case, there is no need to incur the overhead of contructing a smart pointer object. But if the lifetime of the object is always uncertain and you're worried about memory leaks, then by all means use method 2. Methods 3 and 4 are incorrect.
You need memory management, there is no other viable choice. However you may not need memory management from within the factory method.
The main issue with smart pointers is their absence of covariance, which is pain when implementing a clone
virtual method. Unfortunately the covariance rule is not relaxed in C++0x so it remains an issue.
On the other hand, returning a raw pointer and leaving it up to the caller to wrap it up, is opening the door to bugs (even though it's the approach Boost elected for its clones).
Personally, I would suggest:
- the infamous
auto_ptr
or a plain pointer that the caller should wrap in C++03 - a
unique_ptr
as soon as your compiler gets it
The latter combine most advantages (leaving covariance aside), and includes little to no performance overhead.
After having struggled with method 1, I can assure you that method 2, either returning boost::shared_ptr
or boost::scoped_ptr
(usually the former is what you want, if you don't have access to std::unique_ptr
) is what I wholeheartedly recommand.
精彩评论