I am in the process of making a simulation and it requires the creation of multiple, rather similar models. My idea is to have a class called Model and use static factory methods to construct a model. For example; Model::createTriangle or Model::createFromFile. I took this idea from previous java code and was looking for ways to implement this in C++.
Here is what I came up with so far:
#include <iostream>
class Object {
int id;
public:
void print() { std::cout << id << std::endl; }
static Object &createWithID(int id) {
Object *obj = new Object();
obj->id = id;
return *obj;
}
};
int main() {
Object obj = Object::createWithID(3);
obj.print();
return 0;
}
Some questions about this:
- Is this an accepted and clean way of making objects?
- Does the returned reference always ensure correct removal of the object?
- Is there any way to do this without pointers?
It is (unfortunately) accepted but it's not clean.
Instead of factory functions just use constructors.
That's what they're for.
The reference is irrelevant except to the extent that it misleads users of the function.
In your example the reference has apparently misled yourself into not destroying the dynamically allocated object, but just copying it.
Better return a smart pointer.
But as already mentioned, it's even better to ditch the idea of factory functions.
They're wholly unnecessary here.
No, not if "this" refers to the dynamic allocation, but you can and should use constructors instead of factory functions.
Example:
Unless you are using polymorphism there is no reason for your factory functions to return any kind of pointer, they can just return the object by value. Any modern compiler will do return value optimization so there is no copy.
If you are after an "accepted and clean" way then that sounds quite opinion based and dependent on how this class will be used but what I would do is keep the definition of
Model
as small as possible. Only include what is needed for it to do its job with a minimum number of constructors required for normal usage:Then, I would define the functions to create various flavors of
Model
separately. For example, as non-member, non-friend functions in a namespace:That way, if you find you need another flavor of
Model
, you don't need to change theModel
class. Your create functions can even be spread across multiple files if needed or become part of a Builder or Factory class. Usage would look like:This is an absolutely terrible way to create your objects. Every time that
createWithID
is called, a newObject
is constructed on the free store which is never able to be destroyed.You should rewrite
createWithID
to:Or better, you could just supply a constructor for your
Object
objects.If you want to enable polymorphic objects, you should use something like wheels::value_ptr.
Your code currently contains a memory leak: any object created using
new
, must be cleaned up usingdelete
. ThecreateWithID
method should preferably not usenew
at all and look something like this:This appears to require an additional copy of the object, but in reality return value optimization will typically cause this copy to be optimized away.
Just for the record, here's how this program might look like in proper C++:
This is probably not what people would generally call a "factory", since factories typically involve some dynamic type selection. The term "named constructor" is sometimes used, though, to refer to the static member function that returns an instance of the class.
By calling
Object *obj = new Object();
you do allocate memory on the heap. In the lines following that statement you do return the reference to that object. So far, so good, but you do never delete the object you created to actually free the memory. By calling the function several times you will run in a memory leak.There are two possible workarounds:
static Object createWithID(int id);
would return a copy of the Object you create, so it would be enough to allocate it on the stack usinguse c++11 smart pointer to let them handle the memory.