Constructer Calling order - c++

I know when a constructer is being called, then it gets created in the memory, and when it gets out of the block it gets destroyed unless it's static.
Know I have this code:
#include <iostream>
#include <string>
using namespace std;
class CreateSample
{
private:
int id;
public:
CreateSample(int i)
{
id = i;
cout << "Object " << id << " is created" << endl;
}
~CreateSample()
{
cout << "Object " << id << " is destroyed" << endl;
}
};
void fuct()
{
CreateSample o1(1);
static CreateSample o2(2);
}
CreateSample o3(3);
void fuct2(CreateSample o);
int main()
{
fuct();
static CreateSample o4(4);
CreateSample o5(5);
fuct2(o5);
return 0;
}
void fuct2(CreateSample o)
{
CreateSample o6 = o;
}
and my concern is in object o5, why it's getting called once and gets destroyed 3 times?

When you wrote fuct2(o5); you're calling the function fuct2 and passing the argument by value. This means a copy of the argument will be passed to the function using the implicitly defined copy constructor. Thus you get the 2nd destructor call corresponding this object o.
Moreover, in fuct2 you have CreateSample o6 = o; which will also use the implicitly defined copy constructor to create o6. Thus you will get a third call to the destructor corresponding to this o6.
You can confirm this for yourself by adding a copy ctor as shown below:
class CreateSample
{
//other code here
public:
CreateSample(const CreateSample&obj): id(obj.id)
{
std::cout<<"Copy ctor called"<<std::endl;
}
};
And the output you will get is:
Object 5 is created <------ctor called for o5
Copy ctor called <------copy ctor called for parameter o
Copy ctor called <------copy ctor called for object o6
Object 5 is destroyed <------destructor called for o6
Object 5 is destroyed <------destructor called for o
Object 5 is destroyed <------destructor called for o5
Demo
Though in this particular example you don't strictly require a custom copy constructor or a custom copy assignment operator, they may be needed in other situations. Refer to the rule of three.

CreateSample o5(5); calls the constructor CreateSample(int). fuct2(o5); and CreateSample o6 = o; call the implicitly-defined default copy constructor CreateSample(CreateSample const&). All three of these variables (o6, o, and o5) call the destructor ~CreateSample() when their scope is exited.
The fix is to follow the rule of three and also define a copy constructor and copy-assignment operator:
class CreateSample
{
// ...
CreateSample(CreateSample const& o) {
id = o.id;
cout << "Object " << id << " is copy-constructed" << endl;
}
CreateSample& operator=(CreateSample const& o) {
cout << "Object " << id << " is copy-assigned from " << o.id << endl;
id = o.id;
return *this;
}
}
Demo on Compiler Explorer

Related

When the object destructed while I pass the argument by-value?

given the following code:
#include <iostream>
using namespace std;
class A {
public:
A() {
}
A(const A& a) {
cout << "A copy ctor" << endl;
}
virtual ~A() {
cout << "A dtor" << endl;
}
virtual void type() const {
cout << "This is A" << endl;
}
};
class B: public A {
public:
virtual ~B() {
cout << "B dtor" << endl;
}
virtual void type() const {
cout << "This is B" << endl;
}
};
A f(A a) {
a.type();
return a;
}
const A& g(const A& a) {
a.type();
return a;
}
int main() {
A *pa = new B();
cout << "applying function f:" << endl;
f(*pa).type();
cout << "~~~ delete: ~~~" << endl;
delete pa;
return 0;
}
I get the following output:
applying function f:
A copy ctor
This is A
A copy ctor
This is A
A dtor
A dtor
~~~ delete: ~~~
B dtor
A dtor
But I don't understand something. It's seen that while we exists from f the object there is not destructed. Why it's not destructed? (After all, we get out of the scope of the function, so it has to be destroyed, no?)
Note: I emphasized the problematic lines (which I do not understand why it happens in this order)
We going to the function f, at this point, we call to the copy c'tor and printed "A copy ctor" (Ok) , after it, we returns to the function f and going to type() , and then, it's prints "This is A" , now we escpaes from the function f so we calls to the copy c'tor , hence will be printed "A copy ctor" , But, now, what the destructor is not called (while we escape from the function f)..?
I thought that the output will be the following (according to the description above) :
applying function f:
A copy ctor
This is A
A copy ctor (escape from type)
A dtor (escape from type)
This is A (at the main)
~~~ delete: ~~~
B dtor
A dtor
The C++ standard permits by-value function arguments to be destroyed either within the scope of the function, or in the calling scope.
If in the calling scope, it is destroyed at the end of the full expression (usually the ;). If within the function, it is destroyed after the return value is constructed and automatic storage locals are destroyed.
A *pa = new B();
A B is created, with an A subobject base.
cout << "applying function f:" << endl;
f(*pa)//.type();
A sliced copy of *pa is created as the argument to f. Output is A copy ctor\n.
A f(A a) {
a.type();
return a;
}
A .type. is invoked on an instance of A. Note that this A is a copy of *pa, but it is a copy of only the A portion of *pa.
Output is This is A, followed by A(A&&) move ctor, followed optionally by A dtor. In your case you have a copy ctor and not a move ctor, so it is called. This copy/move cannot be elided, as you aren't allowed to elide from function arguments. Output is A copy ctor.
At this point, the compiler may optionally destory the A that is an argument to f. Your compiler does not destroy the argumen to f here.
f(*pa).type();
The temporary A returned by f now has .type() invoked on it. There is no polymorphism here; the method A::type() is called directly. Output is This is A.
Then we reach tne end of the full expression.
Now the temporary returned by f is destroyed, followed by the argument of f if it wasn't destroyed earlier. So output is A dtor.
cout << "~~~ delete: ~~~" << endl;
delete pa;
The B object *pa is destroyed, and then the memory is recycled. As ~A is virtual the proper destructor is called on *pa.
Output is B dtor\nA dtor\n.
The behavior of when the destruction of function parameters occur is implementation defined:
[expr.call]/4
It is implementation-defined whether the lifetime of a parameter ends when the function in which it is defined returns or at the end of the enclosing full-expression.
In your specific case, the implementation chooses the later.

C++ Passing class by value

When i run the following program in XCode Version 5.1.1,
#include <iostream>
class MyClass
{
public:
MyClass() { std::cout << "MyClass Cons " << this << std::endl;}
~MyClass() { std::cout << "MyClass Dest " << this << std::endl;}
};
void Func(MyClass myClass)
{
}
int main(int argc, const char * argv[])
{
MyClass myClass1;
Func(myClass1);
return 0;
}
The output i get is
MyClass Cons 0x7fff5fbff918
MyClass Dest 0x7fff5fbff910
MyClass Dest 0x7fff5fbff918
Why is the destructor triggering twice and constructor only once?
The object is destroyed once, as you can see from the pointer values. You also see the destruction of another object. This object is a copy of the original.
By passing the object by value, the copy-constructor is invoked. Since this constructor does not print something, you do not see it in your output.
Add it to the class definition:
MyClass(const MyClass & other) { std::cout << "MyClass Copy-Cons " << this << " from " << &other << std::endl;}
And it should appear:
MyClass Cons 0x7fff1beee7ee
MyClass Copy-Cons 0x7fff1beee7ef from 0x7fff1beee7ee
MyClass Dest 0x7fff1beee7ef
MyClass Dest 0x7fff1beee7ee
The copy is created when you enter Func(). The copy is destroyed when it goes out of scope. This happens when you exit Func(). Finally, the original is destroyed when you exit the main() function.
The reason that you are seeing two destructor is because you are pass the arguments by value. Passing by value calls the copy constructor..
First Destructor:
At the end of the func function, the object goes out of scope, hence, it is destructed.
Second Destructor:
When the program end, the object is destructed.
My suggestion to remove the first destructor is to pass the object by reference rather than by value.
For example,
void Func(MyClass &myClass)
{
}
So now the output will have only:
MyClass Cons 0x7fff5fbff918
MyClass Dest 0x7fff5fbff918
Here the object is constructed twice(as everyone mentioned above). Hence 2 constructor + 2 destructor are called. The reason you are seeing 1 constructor is because you have NOT defined the Copy Constructor. CC is called when a copy is made for the pass-by-value operation.
add the copy constructor and then you can see both the constructor called.
Add Copy constructor - MyClass(const MyClass& obj) { std::cout << "MyClass Copy Cons " << this << std::endl;}

Why is the destructor called twice? [duplicate]

This question already has answers here:
Why is the destructor of the class called twice?
(5 answers)
Closed 9 years ago.
#include <iostream>
using namespace std;
class A
{
public:
A() { cout << "A's constructor" << endl; }
~A() { cout << "A's destructor" << endl; }
};
class B
{
public:
operator A() const { return A(); }
};
void f(A q) {}
int main()
{
B d1;
f(d1);
return 0;
}
Here's what I expected the code to do before I ran it:
The call to f results in a call to the converter function in class B which returns a temporary object. q's constructor gets called and when f exits, q's destructor gets called. I expected the following output:
A's constructor
A's destructor
but the output I got was:
A's constructor
A's destructor
A's destructor
Since there's another destructor, an extra object must have been created somewhere. Can someone explain what's happening here?
Use this as your class A:
class A
{
public:
A() { cout << "A's constructor: " << this << endl; }
A(const A& a) { cout << "A's copy constructor: " <<this << " form " << &a << endl; }
A(A&& a) { cout << "A's move constructor: " <<this << " form " << &a << endl; }
A& operator=(const A& a) { cout << "A's assignment" <<this << " form " << &a << endl; }
~A() { cout << "A's destructor: "<< this << endl; }
};
And you'll see why.
The question has been asked many times before, but since it is so generic it is difficult to find the older posts.
You are passing your objects around by value, meaning that the copies are created by copy constructor. Copy constructor is what created that "extra object" in your case. Meanwhile, you do not output anything from the copy constructor and therefore don't see the calls.
You have to add a debug output to your copy-constructor as well. That way you will see what is actually constructed and when.
There's potential for there to be 3 A objects constructed here. First is the temporary object created by A() in the conversion operator. Then, since the return type of the conversion operator is A, that temporary is copied into the return value. Then the return value of the conversion is copied into the parameter q of f.
To copy an object, the copy constructor is invoked. The default constructor will not be invoked, so you won't see the "A's constructor" message being printed.
It just so happens that the compiler elides one of these copies so that you only actually have one copy occur. Which one is being elided, I can't tell you (but it's probably the copy into the return value).
I think first destructor call for temporary object and second destructor for object which is constructed by move semantic.

InnerClass object being a member of OuterClass object is created twice

I have two classes: OuterClass and InnerClass. InnerClass is a private member of OuterClass and should be created in OuterClass constructor with an InnerClass(int) constructor, however the default InnerClass constructor is still called.
InnerClass.hpp:
#ifndef INNERCLASS_HPP_
#define INNERCLASS_HPP_
class InnerClass {
public:
int a;
InnerClass();
InnerClass(int);
~InnerClass();
};
#endif /* INNERCLASS_HPP_ */
InnerClass.cpp:
#include "InnerClass.hpp"
#include <iostream>
InnerClass::InnerClass() {
a = 1;
std::cout << "inner class constructed, a = " << a << std::endl;
}
InnerClass::InnerClass(int x) {
a = x;
std::cout << "inner class constructed, a = " << a << std::endl;
//automatically: object InnerClass (a=3) is destroyed here...
}
InnerClass::~InnerClass() {
std::cout << "inner class destructed, a = " << a << std::endl;
}
OuterClass.hpp:
#ifndef OUTERCLASS_HPP_
#define OUTERCLASS_HPP_
#include "InnerClass.hpp"
class OuterClass {
private:
InnerClass blah;
public:
OuterClass();
~OuterClass();
void doSth();
};
#endif /* OUTERCLASS_HPP_ */
OuterClass.cpp:
#include "OuterClass.hpp"
#include <iostream>
OuterClass::OuterClass() {
// automatically: blah = InnerClass();
std::cout << "outer class constructing started, blah.a = " << blah.a << std::endl;
blah = InnerClass(3);
std::cout << "outer class constructed" << std::endl;
}
OuterClass::~OuterClass() {
std::cout << "outer class destructed" << std::endl;
}
void OuterClass::doSth() {
std::cout << "doSth: " << blah.a << std::endl;
}
main:
#include "OuterClass.hpp"
#include <iostream>
int main(int argc, char** argv) {
std::cout << "Compiled at " << __TIME__ << std::endl;
OuterClass x = OuterClass();
x.doSth();
std::cout << "done" << std::endl;
}
output:
Compiled at 12:11:12
inner class constructed, a = 1 //this is unexpected
outer class constructing started, blah.a = 1 //this should be random data
inner class constructed, a = 3
inner class destructed, a = 3 //this is unexpected
outer class constructed
doSth: 3
done
outer class destructed
inner class destructed, a = 3
Questions:
Why is the default constructor of InnerClass called at the start of OuterClass constructor?
What and why is destructed in OuterClass constructor ("inner class destructed, a = 3 //this is unexpected")?
It seems that InnerClass object with a = 3 was destructed in the OuterClass constructor, than why does method doSth() return 3 instead of random data?
Why does removing an InnerClass() constructor (from both InnerClass.hpp and InnerClass.cpp files) result in compile-time error at the OuterClass constructor in OuterClass.cpp file? The error says that no InnerClass() definition found.
Use initializer-list in constructor.
OuterClass::OuterClass() : blah(3) {
// automatically: blah = InnerClass();
std::cout << "outer class constructing started, blah.a = " << blah.a << std::endl;
std::cout << "outer class constructed" << std::endl;
}
Since when you use
OuterClass::OuterClass() {
// automatically: blah = InnerClass();
std::cout << "outer class constructing started, blah.a = " << blah.a << std::endl;
blah = InnerClass(3);
std::cout << "outer class constructed" << std::endl;
}
firstly for initialize blah will be called default c-tor and in blah = InnerClass(3);, that creates temporary object and copy it to blah, after this string will be called destructor of temporary object.
1) Why is the default constructor of InnerClass called at the start of OuterClass constructor?
To construct blah.
2) What and why is destructed in OuterClass constructor ("inner class destructed, a = 3 //this is unexpected")?
The InnerClass(3) you constructed in the second line of the constructor. The one you used to hold the value you assigned to blah. It is destructed because it goes out of scope once the assignment to blah is complete.
3) It seems that InnerClass object with a = 3 was destructed in the OuterClass constructor, than why does method doSth() return 3 instead of random data?
Because you assigned the value 3 to blah. Your code reads;
blah = InnerClass(3);
This creates an InnerClass with the value 3 and then copies its value to blah. So both blah and this temporary object have the same value. The temporary is then destroyed.
If you think about it, there is no other sensible way to implement this line of code.
4) Why does removing an InnerClass() constructor (from both InnerClass.hpp and InnerClass.cpp files) result in compile-time error at the OuterClass constructor in OuterClass.cpp file? The error says that no InnerClass() definition found.
Because then you have no way to construct blah in the first place. (As others have pointed out, you probably wanted an initializer list to construct blah right in the first place rather than default constructing it and then having to go to contortions to fix it.)
OuterClass::OuterClass() /* default blah constructor is called here */ {
std::cout << "outer class constructing started, blah.a = " << blah.a << std::endl;
blah = InnerClass(3); /* a temporary InnerClass is created */
std::cout << "outer class constructed" << std::endl;
} //temporary InnerClass destroyed (out of scope)
Use initializer list to prevent calling default constructor as ForEveR suggests
When the constructor of OuterClass starts executing the body, all members must be constructed. Since there is a blah InnerClass member, it got constructed.
When you assign to blah in OuterClass::OuterClass(), there is a temporary instance created. Here's the order of things:
A temporary InnerClass(3) is constructed.
It is assigned to blah.
The temporary value is destructed -- that's why there's a destructor call.
Follows from 2: blah has a set to 3 in the assignment mentioned in #2 above.
One'd infer that in C++ if you have a specialized argument-taking constructors declared, the default constructor is not created behind your back by the compiler anymore. I can't bother to look into the relevant place in the standard right now, editors feel free to correct this one.
It'd have helped you if you instrumented InnerClass as follows:
Keep a static instance counter, and copy it to every instance. That way you'd know which instance is reporting things back.
Manually write InnerClass & operator=(const InnerClass &) to see when is it invoked.
(PS: Are you coming from Java World to C++ by any chance?)
Output explained:
inner class constructed, a = 1 //this is unexpected
InnerClass is constructed with default constructor first
outer class constructing started, blah.a = 1 //this should be random data
This is the value of InnerClass constructed in previous step with default ctor
inner class constructed, a = 3
A temporary InnerClass is constructed with the overloaded ctor and assigned to the blah member (the implicit operator= is called - you can check by overloading the operator=)
inner class destructed, a = 3 //this is unexpected
The temporary InerClass created in the previous step is destroyed
outer class constructed
doSth: 3
done
outer class destructed
inner class destructed, a = 3
Answers:
Why is the default constructor of InnerClass called at the start of
OuterClass constructor?
Because you have InnerClass member. You should make it a pointer or use initializer list.
OuterClass::OuterClass()
: blah(3)
{
// automatically: blah = InnerClass();
std::cout << "outer class constructing started, blah.a = " << blah.a << std::endl;
// blah = InnerClass(3);
std::cout << "outer class constructed" << std::endl;
}
What and why is destructed in OuterClass
constructor ("inner class destructed, a = 3 //this is unexpected")?
The temporary InnerClass is destroyed here.
It seems that InnerClass object with a = 3 was destructed in the
OuterClass constructor, than why does method doSth() return 3
instead of random data?
The blah member now has a copy of InnerClass object with value 3
Why does removing an InnerClass()
constructor (from both InnerClass.hpp and InnerClass.cpp files)
result in compile-time error at the OuterClass constructor in
OuterClass.cpp file? The error says that no InnerClass() definition
found.
You mean removing the default constructor. Yes, the error is expected because blah member is first created with default ctor.

Why isn't copy constructor being called like I expect here using map?

I am having problems using my custom class with a std::map. The class dynamically allocates memory for members, and I do not want to use pointer in the map because I want to ensure that the class takes care of deleting all allocated memory. But the problem I am having is after I add item to map, when that block of code goes out of scope, the objects destructor is called even though it is still on the map. I made a fake bit of code below that shows what I mean. The output is: So the problem is why is the final destructor being called? Thanks in advance and sorry for the long question.
Constructor Called Num:0034B7E8
Default Constructor Called Num:00000000
Copy Constructor Called Num:CCCCCCCC
Copy Constructor Called Num:CDCDCDCD
destructor called Num:CCCCCCCC
destructor called Num:00000000
destructor called Num:0034B7E8
Inserted Num:0034B7E8
class myClass
{
public:
myClass(int num)
{
mnNum = new int();
cout << "Constructor Called Num:" << mnNum << endl;
}
myClass() : mnNum(NULL)
{
cout << "Default Constructor Called Num:" << mnNum << endl;
}
myClass(const myClass &copy)
{
mnNum = new int(copy.mnNum);
cout << "Copy Constructor Called Num:" << mnNum << endl;
}
~myClass()
{
delete mnNum;
mnNum = NULL;
}
int* mnNum;
};
map<string,myClass> mvMyMap;
void testFunction()
{
myClass lcObj(1);
mvMyMap["Test"] = lcObj;
}
int _tmain(int argc, _TCHAR* argv[])
{
testFunction();
cout << "Inserted Num:" << mvMyMap["Test"].mnNum << endl;
return 0;
}
myClass needs a custom assignment operator, in addition to the copy constructor. So when you make an assignment, you'll leak the original value on the left, and eventually double delete the value on the right.
Your constructor ignores the num parameter and never initializes mnNum from it. It should look like:
myClass(int num)
{
mnNum = new int(num);
cout << "Constructor Called Num:" << mnNum << endl;
}
You also need to adjust your copy constructor like this:
myClass(const myClass &copy)
{
mnNum = new int(*copy.mnNum);
cout << "Copy Constructor Called Num:" << mnNum << endl;
}
edit
Derek Ledbetter pointed out that we need an assignment operator, too. And I would suggest making the destructor virtual.