In-class / constructor member initialization - c++

I'll try to summarize what I need in both words and code snippets.
I have a class, Foo, which contains a data member of the type Bar:
class Foo {
public:
Bar instance_of_Bar;
Foo (int some_data)
{
// I need to initialize instance_of_Bar using one of its
// constructors here, but I need to do some processing first
// This is highly discouraged (and I prefer not to use smart pointers here)
instance_of_bar = Bar(..);
// As an unrelated question: will instance_of_Bar be default-initialized
// inside the constructor before the above assignment?
}
}
Obviously, the "correct" way to do it would be to use an initializer list like this:
Foo (int some_data) : instance_of_Bar(some_data) {}
But this is not an option because I need to do some work on some_data before passing it to the Bar constructor.
Hopefully I made myself clear. What would be the RAII way of doing it with minimal overhead and copying (The Bar class is a hefty one).
Thanks a bunch.

"But this is not an option because I need to do some work on some_data before passing it to the Bar constructor."
What about providing another function to "do some work on some_data":
Foo (int some_data) : instance_of_Bar(baz(some_data)) {}
int baz(int some_data) {
// do some work
return some_data;
}

Related

C++ static factory method vs constructor: how to avoid copying?

This question asks for a clean way of implementing a static factory method in C++, and this answer describes a clear way to do so. Return Value Optimization would save us from making an unnecesary copy of Object, thus making this way of creating an Object as efficient as directly invoking a constructor. The overhead of copying i to id inside a private constructor is negligible because it's a small int.
However, the question and answer don't cover a more complex case when Object contains an instance variable that is an instance of class Foo (that requires complex initialization logic) rather than a small primitive type. Suppose I want to construct Foo using the arguments passed to Object. A solution using a constructor would look something like:
class Object {
Foo foo;
public:
Object(const FooArg& fooArg) {
// Create foo using fooArg here
foo = ...
}
}
An alternative with a static factory method analogous to the quoted answer would be, as it appears to me:
class Object {
Foo foo;
explicit Object(const Foo& foo_):
foo(foo_)
{
}
public:
static Object FromFooArg(const FooArg& fooArg) {
// Create foo using fooArg here
Foo foo = ...
return Object(foo);
}
}
Here, the overhead of copying foo_ to foo is no longer necessarily negligible, since Foo can be an arbitrarily complex class. Moreover, as far as I understand (C++ newbie here so I may be wrong), this code implicitly requires for a copy constructor to be defined for Foo.
What would be a similarly clean but also efficient way of implementing this pattern in this case?
To anticipate possible questions about why this is relevant, I consider having constructors with logic more complicated than just copying the arguments to be an anti-pattern. I expect the constructor to:
be guaranteed to work and not throw exceptions,
and not do heavy calculations under the hood.
Thus, I prefer to put complex initialization logic into static methods. Moreover, this approach provides additional benefits such as overloading by static factory method name even when the input argument types are the same, and the possibility of clearly stating what is being done inside in the name of the method.
Thanks to move constructor, you might do:
class Object {
Foo foo;
explicit Object(Foo&& foo_) : foo(std::move(foo_)) {}
public:
static Object FromFooArg(const FooArg& fooArg) {
// Create foo using fooArg here
Foo foo = ...
return Object(std::move(foo));
}
};
If Foo is not movable, wrapping it in smart pointer is a possibility:
class Object {
std::unique_ptr<Foo> foo;
explicit Object(std::unique_ptr<Foo>&& foo_) : foo(std::move(foo_)) {}
public:
static Object FromFooArg(const FooArg& fooArg) {
// Create foo using fooArg here
std::unique_ptr<Foo> foo = ...
return Object(std::move(foo));
}
};
What is wrong with initializing the instance in the constructor directly from the arguments needed to do so?
class Object
{
Foo foo; // or const Foo foo, disallowing assignment
public:
explicit Object(FooCtorArgs const&fooArg,
const AdditionalData*data = nullptr)
: foo(fooArg) // construct instance foo directly from args
{
foo.post_construction(data); // optional; doesn't work with const foo
}
static Object FromFooArg(FooCtorArgs const&fooArg,
const AdditionalData*data = nullptr)
{
return Object{fooArg,data}; // copy avoided by return value optimization
}
};
AFAICT, there is no need to copy/move anything, even if you need to adjust foo post construction.

Using setters in constructor

I'm a Java developer trying to pick up C++. Is it okay to use a setter inside a constructor in order to reuse the sanity checks the setter provides?
For example:
#include <stdexcept>
using namespace std;
class Test {
private:
int foo;
void setFoo(int foo) {
if (foo < 42) {
throw invalid_argument{"Foo < 42."};
}
this->foo = foo;
}
public:
Test(int foo) {
setFoo(foo);
};
};
Yes, it is recommended to do this, basically for the reason you already mentioned.
On the other hand you should ask yourself if you need the setter at all and not directly implement the checks inside the constructor. The reason I am writing this is that setters in general result in mutable state which has many disadvantages as opposed to immutable classes. However sometimes they are required.
Another recommendation: If your class variable is an object and you can modify the constructor of this object, you could put the check into the constructor of this object:
class MyFoo {
public:
MyFoo(int value) {
if (value < 42) {
throw invalid_argument{"Foo < 42."};
}
v = value;
}
private:
int v;
}
This will enable you to use an initialization list in the constructor of your Test class:
Test(int foo) : foo(foo) {}
However, now the check is a property of the class of the variable and no longer one of the owning class.
Yes you can. It's fine as long as your setters are not virtual, because it's inheritance hierarchy in calling right functions as the "this" ptr is not ready yet.
Here is Herb Sutter GOTW on this matter: http://www.gotw.ca/gotw/066.htm
Yes, that's fine as long as it makes sense to have a setter for a particular member variable (have some logic that can't be checked by assignment only for example) . In this example, setFoo could've just taken an unsigned int and the caller would know not to pass negative values. Which in turn could eliminate the check and thus the need for a setter. For more elaborate checks, a setter and usage of that setter in the constructor is just fine.
Short answer: Yes. In fact, your example works.
Long answer: But it is not a good practice. Al least, you have to take care.
In general, a set function works with a constructed object. It is supposed that the invariant of the class holds. The functions in a class are implemented considering the invariant is true.
If you want other functions to be used in a constructor, you would have to write some code. For example, to create an empty object.
For example, if in your class you change setFoo in the future (let's say setFoo changes the member foo only it is larger) you example stop working.
This is okay.
The only situation you cannot call member function is when the base classes are not constructed yet.
can member functions be used to initialize member variables in an initialization list?
I know this doesn't fit your situation. Its just for the sake of completeness:
When you are simply settings member values (without checks like yours in setFoo) it is recommended to use initialization lists in the constructor. This prevents members being "initialized" 2 times: 1. with their default value, 2. with the value that you passed into the constructor.
class Test {
private:
int foo_;
public:
Test(int foo)
: foo_(foo)
{ };
};

Named constructors and temporary lifetime extension

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_ptrs, but then I'm working with both Foo objects as well as auto_ptrs 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:
Code reuse, I would like to move the common initialization out of each of the constructors and into one. I realize I can do this via an init()-type private method called by each constructor, but I just wanted to mention this.
Clarity and resolve ambiguity. Much like the motivation for the named constructor example, parameter types by themselves aren't enough to determine which ctor should be used. Additionally, the 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.
In C++11, you can call other constructors from constructors:
struct X{
X() : ... { ... }
X(int i) : X() { ... }
X(std::string s) : X() { ... }
};
For C++03, the named constructor approach is likely the best and perfectly reasonable, IMHO.
Why not:
class Foo{
private:
int val;
void Init(int v = <some default value>/*What ever here *));
/* ... */
public:
// Base constructor
Foo(){ Init(); } // This provides basic initialization of
Foo(string &s) { Init(s.length); };
Foo(int v) { Init(v); };
};
Seems simpler.

Writing a source function in c++11 properly

My head hurts: I've read so many blogs about C++11x's move semantics that my brain's gone mushy, so please can someone give me a short-but-sweet guide on how to make the following code work efficiently? Given a class Foo, I want to be able to write functions that return Foo objects in different states (sometimes called source functions), and to do this as efficiently as possible.
class Foo {
// Some methods and members
};
Foo getFirstFoo() {
Foo foo;
// Do some things to foo
return foo;
}
Foo getSecondFoo() {
Foo foo;
// Do some different things to foo
return foo;
}
int main() {
Foo f = getFoo();
// use f ...
f = getSecondFoo();
// use f ...
return 0;
}
I don't want to modify Foo much, and the idea is to allow all sorts of Foo objects to be created through a variety of non-member source functions, so adding ever more constructors would be missing the point.
In C++03 my options would be to wrap the returned object in an auto_ptr (a big downside being that the recipient code needs to know to handle a smart pointer), or to cross my fingers and hope that some sort of optimization might take place (likely for the first line in main, less so for the second). C++11x seems to provide something better through move semantics, but how would I take advantage of these? So I need to change the way objects are returns in the source functions, or add some move constructor to Foo, or both?
This is already optimal1, provided that move constructors are generated2:
class Foo {
public:
Foo(Foo&&) = default;
Foo& operator=(Foo&&) = default;
};
Returned values are rvalue references by default.
1 Well.... provided that your class Foo benefits from move construction at all. Remember, move is an optimization of copy. Some copies cannot be improved! E.g, unsuited:
struct Foo { int data; };
struct Foo2 { int data[5<<10]; };
well suited:
struct Foo3 { std::vector<std::string> data; };
See Move semantics - what it's all about? for a more general background on things like this.
2 Not all compilers do support that yet (even if they do implement rvalue references), so you might have to write the
move constructor
move assignment

How do you call a constructor for global objects, for arrays of objects, and for objects inside classes/structs?

How would you call the constructor of the following class in these three situations: Global objects, arrays of objects, and objects contained in another class/struct?
The class with the constructor (used in all three examples):
class Foo {
public:
Foo(int a) { b = a; }
private:
int b;
};
And here are my attempts at calling this constructor:
Global objects
Foo global_foo(3); // works, but I can't control when the constructor is called.
int main() {
// ...
}
Arrays of objects
int main() {
// Array on stack
Foo array_of_foos[30](3); // doesn't work
// Array on heap
Foo *pointer_to_another_array = new Foo(3) [30]; // doesn't work
}
There I'm attempting to call the constructor for all elements of the arrays, but I'd also like to know how to call it on individual elements.
Objects contained in classes/structs
class Bar {
Foo foo(3); // doesn't work
};
int main() {
Bar bar;
}
Global objects
Yours is the only way. On the other hand, try to avoid this. It’s better to use functions (or even other objects) as factories instead. That way, you can control the time of creation.
Arrays of objects
There’s no way to do this directly. Non-POD objects will always be default-constructed. std::fill is often a great help. You might also want to look into allocators and std::uninitialized_fill.
Objects contained in classes/structs
Use initialization lists in your constructor:
class Bar {
Foo foo;
Bar() : foo(3) { }
};
Static members must actually be defined outside the class:
class Bar {
static Foo foo;
};
Foo Bar::foo(3);
To correct some misconceptions about globals:
The order is well defined within a compilation unit.
It is the same as the order of definition
The order across compilation units is undefined.
The order of destruction is the EXACT opposite of creation.
Not something I recommend but: So a simple solution is to to put all globals into a single compilation unit.
Alternatively you can tweak the use of function static variables.
Basically you can have a function the returns a reference to the global you want (defining the global inside the function). It will be created on first use (and destroyed in reverse order of creation).
Foo& getGlobalA() // passed parameters can be passed to constructor
{
static Foo A;
return A;
}
Foo& getGlobalB()
{
static Foo B;
return B;
}
etc.
The Konrad reply is OK, just a puntualization about the arrays....
There is a way to create an array of items(not pointers) and here it follows:
//allocate raw memory for our array
void *rawMemory = operator new[](30 * sizeof(Foo))
// point array_of_foos to this memory so we can use it as an array of Foo
Foo *array_of_foos = static_cast<Foo *>(rawMemory);
// and now we can create the array of objects(NOT pointers to the objects)
// using the buffered new operator
for (int i = 0; i < 30; i++)
new(array_of_foos[i])Foo(3);
This approach is described here: http://www.amazon.com/gp/product/0321334876?ie=UTF8&tag=aristeia.com-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0321334876
For the global case there is no way to control when it is called. The C++ spec essentially says it will be called before main() and will be destroyed sometime afterwards. Other than that' the compiler is free to do as it pleases.
In the first array case you are creating a static array of Foo objects. By default each value in the array will be initialized with the default constructor of Foo(). There is no way with a raw C++ array to force a particular overloaded constructor to be called. You can infer a bit of control by switching to a vector instead of an array. The vector constructor has an overloaded constructor vector(size,defaultValue) which should achieve what you are looking for. But in this case you must be careful because instead of calling Foo(3) it will call Foo(const Foo& other) where other is Foo(3).
The second array case is very similar to the first case. The only real difference is where the memory is allocated (on the heap instead of the stack). It has the same limitation with regards to calling to the constructor.
The contained case is a different issue. C++ has a clear separation between the definition of a field within an object and the initialization of the field. To get this to work in C++ you'll need to change your Bar definition to the following
class Bar{
Foo foo;
Bar() : foo(3){}
};
There seems to be the general gist in this thread that you cannot initialize members of an array other than using the default constructor. One answer even creates another type, just to call another constructor. Even though you can (if the array is not part as a member of a class!):
struct foo {
foo(int a): a(a) { }
explicit foo(std::string s): s(s) { }
private:
int a;
std::string s;
};
/* global */
foo f[] = { foo("global"), foo("array") };
int main() {
/* local */
foo f[] = { 10, 20, 30, foo("a"), foo("b") };
}
The type, however, needs to be copy-able: The items given are copy-initialized into the members of the array.
For arrays as members in classes, it's the best to use containers currently:
struct bar {
/* create a vector of 100 foo's, initialized with "initial" */
bar(): f(100, foo("initial")) { }
private:
std::vector<foo> f;
};
Using the placement-new technique described by andy.gurin is an option too. But note it will complicate things. You will have to call destructors yourself. And if any constructor throws, while you are still building up the array, then you need to figure where you stopped... Altogether, if you want to have arrays in your class, and want to initialize them, use of a std::vector is a simple bet.
Construction of arrays of objects:
You can modify your original example by using default parameters.
Currently only the default constructor is supported.
This is something that is being addressed by the next version (because everybody asks this question)
C++0X initializer lists solve this problem for the arrays of objects case. See this Herb Sutter blog entry, where he describes them in detail.
In the meantime you might be able to work around the problem like so:
class Foo {
public:
Foo(int a) : b(a) {}
private:
int b;
};
class Foo_3 : public Foo {
public:
Foo_3() : Foo(3) {}
};
Foo_3 array_of_foos[30];
Here, the Foo_3 class exists solely for the purpose of calling the Foo constructor with the correct argument. You could make it a template even:
template <int i>
class Foo_n : public Foo {
public:
Foo_n() : Foo(i) {}
};
Foo_n<3> array_of_foos[30];
Again this might not do exactly what you want but may provide some food for thought.
(Also note that in your Foo class you really should get into the habit of using member initializer lists instead of assignments in the constructor, as per my example above)
I reckon there are two ways to make sure global class objects' constructors are called safely at the time of their "creation":
Declare them in a namespace and make that namespace globally accessible.
Make it a global pointer to the class object and assign a new class object to it in main(), granted code for other global objects' constructors that access the object will execute before this.
Just my two cents.