简体   繁体   中英

Return to caller not invoking constructor in C++

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.

  1. 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.
  2. 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?

I guess the part you missed about copy elision is what it implies. If no copy-construction takes place, what does the new (caller-side) object get constructed from?

No copying (or moving) implies there is only one object . That means construction is done right at the destination, ie constructing the return value inside the function == constructing the returned value outside.

This has also nothing to do with your copy-assignment operator AutoPtr operator=(const AutoPtr&) , since AutoPtr<Reference> obj1 = generateRes(); is an initialization .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM