dimanche 23 février 2020

Why does rvalue reference to object continue working after object gets destroyed?

I'm trying to understand the principles of C++11 rvalue references. Here's the example where rvalue reference to object still works, whereas object itself is already destroyed (according to output). Is this an underfined behaviour or something that has a logical explanation? Thanks

#include <iostream>
class MyClass
{
public:
    static int cnt;
    MyClass(const int& par) :
        m_par(par)
    {
        cnt++;
        std::cout<<"ctor called (par="<<m_par<<", cnt = "<<cnt<<std::endl;
    }
    MyClass(const MyClass& other)
    {
        cnt++;
        this->m_par = other.m_par;
        std::cout<<"Copy constructor (par="<<m_par<<", cnt = "<<cnt<<std::endl;
    }
    void PrintParamTimesTwo() const
    {
        std::cout<<"Param * 2 = "<<2*m_par<<", cnt = "<<cnt<<std::endl;
    }
    ~MyClass()
    {
        cnt--;
        std::cout<<"destr-r called (par = "<<m_par<<", cnt = " <<cnt<<std::endl;
    }
private:
    int m_par;
};
int MyClass::cnt {0};
MyClass&& GetInstance()
{
    MyClass inst1(10);
    MyClass inst2(20);
    bool condition {false}; // any value
    return condition ? std::move(inst1) : std::move(inst2);
}
void outer_foo()
{
    const MyClass&& objRef = GetInstance();
    objRef.PrintParamTimesTwo();
}
int main()
{
    outer_foo();
    std::cin.get();
}

The output is:

ctor called (par=10, cnt = 1
ctor called (par=20, cnt = 2
destr-r called (par = 20, cnt = 1
destr-r called (par = 10, cnt = 0
Param * 2 = 40, cnt = 0 

Aucun commentaire:

Enregistrer un commentaire