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 if 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 conceren is in object 5, why it's getting called once and gets destroyed 3 times?
CodePudding user response:
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;
}
}
CodePudding user response:
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
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.