Why my c++ move constructor was not called?

93 views Asked by At

I wrote a simple class called Str and overwrote its constructor, copy constructor and move constructor.

class Str
{
public:
    Str(const char* s) :m_data(NULL)
    {
        printf("constructor\n");
        int size = strlen(s) + 1;
        m_data = new char[size];
        strncpy_s(m_data, size, s, size);
    }

    Str(const Str &s) 
    {
        printf("copy constructor\n");
        int size = strlen(s.m_data) + 1;
        m_data = new char[size];
        strncpy_s(m_data, size, s.m_data, size);
    }

    Str(Str &&s)
    {
        printf("move constructor\n");
        m_data = s.m_data;
        s.m_data = NULL;
    }

public:
    char* m_data;
};

Now I have such a function who wants to call its move constructor:

void speak(Str &&s)
{
}
Str getStr()
{
    Str s("cat");
    return s;
}

If I try this way, move constructor can be called.

speak(getStr());

Its output is :

constructor
move constructor

It's because getStr() is a temporary value, so move constructor was called, right? But if I try this way, it cannot.

speak(Str("cat"));

Its output is :

constructor

What I don't understand is that Str("cat") is a temporary value as well. But it only called constructor! Why??

1

There are 1 answers

0
leslie.yao On

What I don't understand is that Str("cat") is a temporary value as well. But it only called constructor! Why??

At first, binding to reference won't cause copy, i.e. no copy/move constructor would be called.

For speak(Str("cat"));, Str("cat") is a temporary, then it's bound to the rvalue-reference parameter s. Nothing needs to be copied, then no copy/move constructor needs to be called.