I'm looking for a way to define a "base" constructor, that will initialize values using defaults, and then extend that base into a number of specialized constructors.
The pseudocode of what I want might look like:
class Foo{
private:
int val;
/* ... */
public:
// Base constructor
Foo(){ /*...*/ } // This provides basic initialization of members
// Named constructors
static Foo fromString(string s){
Foo f; // Call base constructor
f.val = s.length(); // Customize base object
return f; // Return customized object
}
static Foo fromInt(int v){
Foo f;
f.val = v;
return f;
}
}
At first, I thought about extending the lifetime of the temporary f
, but the const declaration prevents me from editing its members. So it seems this is out.
Then I tried the "named constructor" approach (which is shown above). However, I had to modify the example to create the object first, then modify it, then return it. This seems to work, but I'm reasonably confident that it is just a coincidence since f
is a temporary and goes out of scope at the end of the function.
I've also considered using something like auto_ptr
s, but then I'm working with both Foo objects as well as auto_ptr
s to Foo, and this makes the rest of the code "care" whether objects are created via the base constructor (in which case it would be an object) or via one of the extended constructors (in which case it would be a pointer).
If it helps, in Python, I would use something like this:
class Foo(object):
def __init__(self):
/* Basic initialization */
@classmethod
def fromString(cls, s):
f = Foo() #†
f.val = len(s)
return f
Lastly, there are two reasons I want to do it this way:
init()
-type private method called by each constructor, but I just wanted to mention this.fromSomething
syntax provides excellent clarity.Forgive me if there is a simple solution, my work has shifted from c++ to Java/Python for the past few years so I'm a bit rusty.
This is perfectly valid:
static Foo fromInt(int v){
Foo f;
f.val = v;
return f;
}
This invokes Foo
's copy constructor when you return f
(probably the compiler applies return value optimization, so no copies are made). f
goes out of scope, but the return value is just a copy of it, so this is totally valid, it's not just "a coincidence" that it's working.
So if your worries about using the named constructor approach is just that you don't really know if it works, go ahead with it, it works perfectly.