Why constructor is called only once? - c++

Consider the below program:
class A
{
public:
A(int i)
{
cout<<"Called"<<endl;
}
};
int main()
{
vector<A> v(5,A(1));
return 0;
}
I am getting the output: http://ideone.com/81XO6
Called
Why the constructor gets called only once even if we are constructing 5 objects?
How vector is internally handled by the compiler?

Your class has two constructors and you are watching only one of them. std::vector creates its elements by copy-constructing them from the original element you supplied. For that purpose, the copy-constructor of class A is called 5 times in your example.
The copy-constructor for A in your example is implicitly declared and defined by the compiler. If you so desire, you can declare and define it yourself. If you print something from it, you will see that it is called at least 5 times.

It gets called once since the line
vector<A> v(5,A(1));
will call the constructor and the line becomes
vector v(5,X);
where X is the object constructed after calling the constructor.
After that the copy constructor is used.
Try adding
A(const &A);
To the class declaration to verify this.

Related

C++ another unique_ptr incomplete type question

Have looked at various similar questions here but still can't figure out why the following code does not compile:
// these three are defined somewhere
class A;
std::unique_ptr<A> make_a();
void take_a(std::unique_ptr<A>&&);
int main(){
take_a(make_a()); // this fails
return 0;
}
According to this:
If the default deleter is used, T must be complete at the point in
code where the deleter is invoked, which happens in the destructor,
move assignment operator, and reset member function of
std::unique_ptr.
As far as I understand, none of these (destructor, move assignment operator, nor reset member function) happens in main.
So why does compiler needs the definition of A here?
Since main has a unique_ptr within its scope, realistically it would need to know how to delete the object it holds.
It's possible that take_a doesn't actually take ownership of the object, thus main would need to delete.
main gets a temporary unique_ptr from make_a(), let's call it X. It then passes an rvalue reference to X to take_a. It still has the destroy X. Hence, it has to call the destructor after take_a, even though X would typically be empty at that point.
We need class A description (at least constructor and destructor) in order to create and move std::unique_ptr<A> objects; take_a(make_a()) is creating such object because make_a() is pass-by-value. It first creates a new unique_ptr<A> object, initialize it (using default constructor), and then update its value and returns this new object. Here the default constructor/destructor is being used, which the compiler is unable to find.
#include <bits/stdc++.h>
class A {
public: A() {}
public: ~A() {}
};
std::unique_ptr<A> make_a() {
std::cout << "make";
std::unique_ptr <A> tt = nullptr;
return tt;
}
void take_a(std::unique_ptr<A>&&) {
std::cout << "take";
}
int main(){
take_a(make_a()); // this works now
return 0;
}
Edit: Forgot to add the link. Works the other way too.

Vector and push_back() behavior

I'm studying to understand class constructor and destructor.
I have written a small console code to add one class instance in to a vector. All is nice and dandy, but what I fail to understand is, that adding one Object in to the vector triggers destructor twice. Why does this happen?
If I don't add any object, the vector doesn't trigger constructor or destructor on its own, so why it happens twice?
Can anyone explain why this happens?
#include <cstdio>
#include <vector>
class Test
{
private:
int value;
public:
Test()
{
printf("\nClass constructor triggered.");
};
~Test()
{
printf("\nClass desctructor triggered.");
}
};
int main()
{
std::vector<Test> container;
container.push_back( Test() );
return 0;
}
UPDATE:
I added some more information to the class so that I get more specific output, however now I noticed that with each addition to the vector the move-construction and destructor calls increase. Are the amount of these calls tied to the amount of objects within the vector or what is happening?
Am I having a leak? Sorry if too stupid questions.
Below is the added code:
#include <cstdio>
#include <vector>
class Test
{
private:
int value;
public:
// Constructor
Test(int v=0)
{
value = v;
printf("\n\n%i", value);
printf("\nClass constructor triggered.");
};
// Copy-move constructor
Test(Test&&)
{
printf("\nClass move-constructor triggered.");
};
// Destructor
~Test()
{
value = 0;
printf("\nClass desctructor triggered.");
}
};
int main()
{
std::vector<Test> container;
container.push_back( Test(1) );
container.push_back( Test(2) );
container.push_back( Test(3) );
container.push_back( Test(4) );
printf("\n\nPushback complete!");
return 0;
}
Your vector contains a copy of the object you add to it through push_back(). The first destructor invocation is caused by the temporary you create being destroyed at the end of the full expression containing the call to push_back(). The second destructor is caused by the copy inside the vector being destroyed when the vector itself is destroyed.
You can convince yourself by adding a diagnostic to main():
int main()
{
std::vector<Test> container;
container.push_back( Test() );
printf("\nThis is before the vector is destroyed...");
return 0;
}
You can observe the output in this live example.
The copy which your vector contains is created by invoking the automatically-generated move constructor for your class (rather than using default construction), which is why you don't see a corresponding construction diagnostic.
If you defined your own move constructor (or copy constructor, as shown below) to emit a diagnostic, the output would be closer to what you'd expect:
Test(Test const&)
{
printf("\nCopy construction triggered.");
};
Again, live example.
Because you don't print every constructor invocation, you're missing out on move-constructor call. Your class, apart from the default constructor you've provided, has also implicitly generated move and copy constructors.
The vector stores a value, and that value has to be initialized in some way. Typically, this happens either via a move c-tor or copy c-tor, altough an object might also be created directly inside of the vector using e.g. emplace_back.
Try adding this:
Test(Test&&)
{
printf("\nClass move constructor triggered.");
};
to your class, it should change the output to something that makes more sense (I've also added a print at the end of main):
Live On Coliru
Class constructor triggered.
Class moveconstructor triggered.
Class desctructor triggered.
Out of main scope.
Class desctructor triggered.
The first destructor call destroys moved-out "empty" instance of your class, while the second one fires when the vector itself is destroyed.
The push_back() does not trigger any destructor (in this case).
The two calls to Test's destructor are:
1 - Because you pass a temporary to push_back(), so that object get destroyed when push_back() is done
2 - when the program end, so the vector get destroyed and so it is it's content
For the sake of simplicity, let's assume you are working with C++03, and move semantics are not available yet.
Add copy constructor to see that it is also triggered
Test(const Test&)
{
printf("\nClass copy constructor triggered.");
};
Output
Class constructor triggered.
Class copy constructor triggered.
Class destructor triggered.
Class destructor triggered.
So, there are two objects constructed/destructed.
Roughly speaking, your code is equal to
int main()
{
std::vector<Test> container;
Test test; // first object created
container.push_back(test); // second object created by copying
return 0;
}

Can constructor do any hard job other than passing values to members?

So to summarize initialization in C++ , constructor can
initialize primitive types to garbage values in memory
call default constructors on members automatically
initialize member objects with nontrivial constructors in init list
but it cannot init array properly. Ref:
C++: constructor initializer for arrays
My question is: how can I do meaningful initialization in the function body? Before entering the braces, everything has already been initialized in one way or another. The braces only contain cleaning up work, things like cout<<"This object is constructed!"
. Ref:
Use of constructor in C++
What if I want to preprocess parameter before passing it to the constructor of member object? For example:
class Foo{
public:
int x;
Foo(int y){
x = y;
}
};
class Bar{
public:
Foo foo1;
Bar(int y){
int z = superComplicatedOperation(y);
// and all other heavylifting work
foo1 = A(z);
}
};
The code above does not compile because compiler tries to init foo1 before entering the braces in constructor.
I have seen suggestions on solving this problem by providing a default constructor to Foo. So the constructor of Bar will first init foo1 to garbage value, and then assign foo1 to something meaningful in the ctor body. This is also the solution to array initialization in the quoted thread. But isn't "initializing to garbage value" an oxymoron? If the compiler wants me to do that, then it wouldn't complain about having no default ctor.
In a word, ctor is supposed to init the object in a user defined way, but I don't see any way to do a nontrivial init. Am I missing something here?
================================================================================
Clarifications: I am askingI am well aware of the Bar(int y): foo(superComplicatedOperation(y)) syntax. My question is on how to do it nicely. From a design point of view, I believe that codes in superComplicatedOperation() really should belong to the ctors. For example, say Bar takes 2 parameters (int x,int y) to initialize. We can imagine they are xy coordinates on plane. Foo also takes coordinates, but with a different reference frame. Then I need
Bar(int x,int y):foo(f1(a,b),f2(a,b))
And this kind of things quickly get ugly if ctor has a handful of params. Besides, init list looks crowded.
And if ctor body "touches" member objects, it means init list does not set members to a desired state, but rather some default zero-like states(e.g. empty vector). Therefore when calling ctor, first memory for the Bar is allocated, then members objects(subchunks of memory) go through the phases:
garbage value/uninitialized
--- init list or default member ctor --->
default "zero-like" state
--- ctor body -------------------------->
actually desired initial state
So initialization is supposed to be a two step process?
Preprocessing a parameter is fairly trivial:
class Bar
{
Foo foo;
Bar(int y) : foo(superComplicatedOperation(y)) {}
}
or you can use a C++11 delegating constructor:
class Bar
{
Foo foo;
Bar (SuperComplicatedData z) : foo(z) {}
Bar (int y) : Bar(superComplicatedOperation(y)) {}
}
What can you do in a constructor function body? Lots of things: fill containers, configure member objects, set up member object relationships, etc.
[...] constructor can
initialize primitive types to garbage values in memory
call default constructors on members automatically
This is default-initialization, which applies to every member that's not specified in the initializer list and do not have an initializer in the class definition.
initialize member objects with nontrivial constructors in init list
The member initializer list can also initialize primitive members.
but it cannot init array properly. Ref:
C++: constructor initializer for arrays
One of the answers there noted that this can now be done in C++11.
My question is: how can I do meaningful initialization in the function
body? Before entering the braces, everything has already been
initialized in one way or another. The braces only contain cleaning up
work, things like cout<<"This object is constructed!" . Ref:
Use of constructor in C++
Um...no. Frequently there's substantial logic in the constructor body proper. It's definitely not only for "cleaning up". It is true that at the time you enter the constructor body every member is initialized in some way (which may include "not initialized at all" for primitive types), but nothing says you can't assign to them or otherwise modify them. Sometimes you have to if there's some sort of circular dependencies. Sometimes the code to compute the stored value is long enough that it's far more readable inside the constructor body.
The code above does not compile because compiler tries to init foo1
before entering the braces in constructor.
I have seen suggestions on solving this problem by providing a default
constructor to Foo.
Well, you can do : foo1(A(superComplicatedOperation(y)) in your example.
So the constructor of Bar will first init foo1 to
garbage value, and then assign foo1 to something meaningful in the
ctor body. This is also the solution to array initialization in the
quoted thread. But isn't "initializing to garbage value" an oxymoron?
If the compiler wants me to do that, then it wouldn't complain about
having no default ctor.
A default ctor means that a object constructed with it is a valid object. A default ctor doesn't necessarily leave members uninitialized (or "initialized to garbage values"). Consider the default ctor for a std::vector, it had better set its internal state to something that represents an empty vector!
More fundamentally, the job of constructors (default or not) is to establish the object's invariants upon which the functions that operate on the object depend. Some objects may have no invariants, but many do (for instance, vector's internal pointer had better be either a valid pointer or null). If you have no default constructor, the compiler has no way of creating a valid object when no argument is supplied; it can't just give you something "initialized to garbage value", because it has no way of knowing whether that can in fact be a valid object of that type.
You can use an initializer list, as you should for any member variables you need to initialize.
You may prefer to initialize things to sane values and then have a function that can set the values later. It's not as clean, but if you plan to construct many objects and you can precompute the value for many of them at once it may save you some time rather than calculating the values for each object.
#include <iostream>
int superComplicatedOperation(int a)
{
return a * 10;
}
class Foo
{
public:
int x;
Foo(int y)
: x(y)
{
}
};
class Bar
{
public:
Foo foo1;
Bar(int y)
: foo1(superComplicatedOperation(y))
{
}
};
int main()
{
Bar b(7);
std::cout << b.foo1.x << "\n";
return 0;
}
class Bar {
public:
Foo foo1;
Bar(int y) : foo1(superComplicatedOperation(y)) { }
};
You can use the Constructor's initialization list for this work. It passes the values to the Ctors of the members for the first creation, this prevents the creation of a garbage object.
I guess I don't understand. I wrote code in the 1990s which has a constructor with hundreds of lines of code which does all kinds of things: opens files, instantiates dozens of objects which create linked lists and arrays based on processing file data. It certainly can initialize an array properly.

Constructor execution order in C++

#include <cstdio>
struct A {
int a;
A() {
a = 2;
printf("Default\n");
}
A(int b_) {
a = 1;
if(b_ == 10) {
A();
}
}
};
int main(int argc, char **argv) {
A a(10);
printf("a=%d\n", a.a);
A b(11);
printf("b=%d\n", b.a);
return 0;
}
This prints:
Default
a=1
b=1
That is, it enters the Default constructor when b_ == 10, but not when it's not. But it doesn't change the value in a.a, even though it enters the Default constructor.
Why?
You aren't calling the constructor. You're just creating a temporary A then destroying it immediately. You can't call other constructors from a constructor in the current standard (C++03), and even in C++0x, you can only call other constructors from the initialisation list.
Most answers so far say that you're not calling a constructor. You're seeing the output of the constructor call. So just disregard those answers that are denying reality by over-simplifying.
The code snippet
if(b_ == 10) {
A();
}
creates and destroys a temporary object of class A.
As part of the creation the A default constructor is called to initialize the object.
The C++98 rules are designed to ensure that unless you use very low level functionality to impose your contrary will, every creation of an object of type T corresponds to exactly one T constructor call on that object. And vice versa, if you call a T constructor (which is another valid view of the above code) then, in C++98, you're creating a T object. You can call that the C++ constructor call guarantee: creation = constructor call.
The constructor call guarantee means, among other things, that a constructor call failure is an object creation failure: if a constructor fails, then you don't have an object.
Which simplifies things a lot.
For example, it says that if you do new A, and the A default constructor fails, then you don't have an object. So the memory that was allocated to hold that object, is automatically deallocated. And so that expression does not leak memory even if the object construction fails -- instead of an object, you just get an exception.
It's almost beautiful. :-)
A(); doesn't do what you think it does. (e.g. call the default constructor)
It creates a temporary object, which then is discarded.
A(); creates a new (temporary) instance of A, calling its default constructor.
You cannot call another constructor from a constructor.
If you have a lot of initializing to do, you could create a private method and call it in both constructors.
In this code:
if(b_ == 10) {
A();
}
You're putting a temporary A() on the stack, not calling the default constructor of A.
To do what you intend, you'll need to factor out the code in the default constructor into a helper function, then call that function from here and the default constructor.
With A() (in A(int b)), you are creating a new, different object.
Googlr says this: Can I call a constructor from another constructor (do constructor chaining) in C++?

When are member data constructors called?

I have a global member data object, defined in a header (for class MyMainObj) like this.
class MyMainObj
{
MyDataObj obj;
}
MyDataObj has a default constructor.
When is the constructor for MyDataObj called?
Is it called as part of the creation of MyMainObj?
MyDataObj in this case is not a member of MyMainObj, it's a local variable.
But, constructors for data members are called in your class's constructor. The default constructor for every member is called before execution reaches the first line in the constructor, unless you explicitly specify a constructor using an initializer list, in which case that constructor is called instead.
With that code, obj isn't a member of MyMainObj -- it's simply a local object inside that constructor. As such, it'll only be constructed when/if that constructor is invoked.
Concerning your code, you have a function with a variable inside. Upon entering the function, you will run to the line of code that declares the variable, and the constructor will be run then.
But you say "creation of MyMainObj". It's a function, it can only be called, not created.
This is all concerning the title question, "when are members constructed?" This would apply if MyMainObj was a class and not a function.
Your member objects are constructed in the order of which they appear in the class declaration. All objects are full constructed upon entering the constructor. (But this does not include the class itself!)
That is to say, by the time the class enters its constructor, all the members have finished their constructor.
Objects are destructed in reverse order, in the destructor (after the destructor is run).
In a pseudo-diagram:
MyClass
Member1
Member2
Member3
Construction:
Member1
Member2
Member3
MyClass
Destruction:
MyClass
Member3
Member2
Member1
You can manually call the members constructor using an initialization list:
class foo
{
public:
foo(void) : i(0) // construct i with 0.
{
}
int i;
};
There are various question on SO about initialization lists. Initialization list order, Copy-construction initialization list, and more.
Yes, the constructor would be called whenever a MyMainObj instance is created.
I'm a bit confused by the "global member" terminology - the way you've declared that object it would be a local variable inside the constructor. Am I missing something here?
Yes, as other stated the member will be created on the owner class creation, on construction (be it generated by the compiler or with a provided constructor).
The order of creation will be the same as how your members apear in the class declaration. For example :
class MyType
{
Thing a;
Thing b;
Thing d;
Thing c;
};
Whatever constructor is used, whatever the order in a initialization list, the members will be constructed in this order : a, b, d, c. Once it's all done, the constructor code will be executed (if it exists) and only then your whole object will be constructed.
Upon entering an object constructor, memory has already been allocated for it. Then the execution order is as follows:
Base class constructor, if any, as specified in the initialisation list; if not specified, the default constructor is used.
The constructors for the member data, as specified in the initalisation list (default if not specified), in the order they are declared in the class definition. The order in which they are specified in the initialisation list is irrelevant.
The constructor body.
In the example set in the question, the first thing that would be executed upon entering the default constructor of MyMainObj would be the default constructor of MyDataObj to construct the member data obj.
Given a class A:
class A {
MyDataObj obj;
}
If you don't write the constructor for A, the compiler will create one for you, which will create obj as part of constructing A (and destroy obj as part of destroying A.
If you do write a constructor for A, then obj will be created before your constructor runs, although you can reassign it:
class A {
MyDataObj obj;
public:
A() { } // obj created, but the value may or may not be predictable
}
class AA {
MyDataObj obj;
public:
AA()
{
obj = MyDataObj(5);
}
}
class AAA {
MyDataObj obj;
public:
AAA() : obj(5) { } // member initializer list, my preferred method
}
With the third option, the data objects are created before the member initializer list runs, and the values are assigned in the order they are declared in AAA, NOT the order they are listed in the member initializer list.
UPDATE: There is a difference between creation and initialization. Space for the data members (and the base classes, and the data members for the base classes) is always set aside -- which I would call "creation." However, that doesn't mean a useful value is stored in that memory. There are separate rules for whether an object is default initialized, which depend on the type of the data member (primitive, POD, non-POD) and, IIRC, the storage class of the main object (local, static, global). The easiest way to avoid surprises in this area is to simply make sure you explicitly initialize everything.