Reputation: 195
#include <iostream>
using namespace std;
class CCC {
public:
CCC() {cout<<"created "<<++count<<endl;}
~CCC(){cout<<"deleted "<<--count<<endl;}
int count=0;
};
CCC a;
CCC& create() {
return a;
}
int main () {
CCC result = create();
}
The above code produces strange output. Looks like the destructor is called 2 times, but count is not decremented. Why is that?
created 1
deleted 0
deleted 0
Upvotes: 2
Views: 147
Reputation: 785
This is because of the implicitly defined copy constructor.
It will copy the state of the other class by default, like:
CCC(const CCC& other): count(other.count)
For a full example see below.
#include <iostream>
using namespace std;
class CCC {
public:
CCC() {cout<<"created "<<++count<<endl;}
CCC(const CCC& other): count(other.count) {cout<<"copied " << count << " others count " << other.count << endl;}
~CCC(){cout<<"deleted "<<--count<<endl;}
int count=0;
};
CCC a;
CCC& create() {
return a;
}
int main () {
CCC result = create();
}
Upvotes: 0
Reputation: 310960
In this statement
CCC result = create();
there was used the default copy constructor.
So the object result has the same value of the data member count
as the global object a
.
Then destructors for the both objects were called decreasing corresponding data members count
.
It seems what you are trying to do is either the following
#include <iostream>
using namespace std;
class CCC {
public:
CCC() {cout<<"created "<<++count<<endl;}
CCC( const CCC & ) {cout<<"created "<<++count<<endl;}
~CCC(){cout<<"deleted "<<--count<<endl;}
int count = 0;
};
CCC a;
CCC& create() {
return a;
}
int main () {
CCC result = create();
}
and the program output is
created 1
created 1
deleted 0
deleted 0
or the following
#include <iostream>
using namespace std;
class CCC {
public:
CCC() {cout<<"created "<<++count<<endl;}
CCC( const CCC & ) {cout<<"created "<<++count<<endl;}
~CCC(){cout<<"deleted "<<--count<<endl;}
static int count;
};
int CCC::count = 0;
CCC a;
CCC& create() {
return a;
}
int main () {
CCC result = create();
}
In this case the program output is
created 1
created 2
deleted 1
deleted 0
Upvotes: 3
Reputation: 119144
The count
member is non-static, so each instance of CCC
has its own copy.
For the instance a
, the count
member will be set to 0 when the default constructor starts, then incremented to 1 and printed. Later it will be destroyed, the count
member decremented to 0, and printed again.
For the instance result
, the count
member is set to 1 by the copy constructor since it was 1 in a
. When it is destroyed, the member is decremented to 0 and printed again.
If you wanted to track the total number of instances of the class that exist, you would need a static member,
static int count = 0;
Furthermore, you would need to increment it not only in the default constructor, but also in the copy and move constructors.
Upvotes: 7
Reputation: 1804
There are different types of constructor. You have instrumented the default constructor, but not the copy or move constructor. Please read up on the c++ rule of 3 / rule of 5 for more information.
Upvotes: 1