I am learning about copy elision and tried out something to learn about it. But there is something unexpected happening with the below code:
template<typename T>
class AutoPtr
{
T* m_ref;
public:
AutoPtr(T* ref)
{
printf("Cons called\n");
m_ref = ref;
}
AutoPtr(const AutoPtr& autoPtr)
{
printf("Copy called\n");
m_ref = autoPtr.m_ref;
}
~AutoPtr()
{
delete m_ref;
}
};
class Reference
{
public:
Reference()
{
printf("Reference created\n");
}
~Reference()
{
printf("Reference deleted\n");
}
};
AutoPtr<Reference> generateRes()
{
Reference *ref = new Reference();
//Scenario 1
//AutoPtr<Reference> temp{ref};
//return temp;
//Scenario 2
return AutoPtr<Reference>{ref};
}
int main()
{
AutoPtr<Reference> obj1 = generateRes();
return 0;
}
In the above code, I am trying 2 scenarios.
- Initializing a temp AutoPtr object and then returning it. Here, constructor is called when temp is initialized. But in the main function, when obj1 is initialized, constructor is not called.
- Directly returning temporary object. Here in the main function, obj1 is initialized and constructor is called.
Why doesn't scenario 1 call constructor for obj1? Is it some compiler optimization? I know that copy elision has happened and copy constructor is not called, but why is the normal constructor not called twice?