當以一個函數內的臨時變量對象作為另一個函數的形參的時候,原函數內的臨時對象即 rvalue,就會成為此函數內的 lvalue。
這樣會重新導致效率低下,因為造成了大量復制操作。
<utility>頭文件提供了 std:move()函數。此函數返回作為 rvalue 傳遞給的任何實參。
觀察下面程序的輸出:
class CText
{
private:
char *pText;
public:
void showIt()const
{
cout << pText << endl;
}
CText(const char* pStr = "No text")
{
cout << "CText constructor called" << endl;
size_t len{ strlen(pStr) + 1 };
pText = new char[len];
strcpy_s(pText, len, pStr);
}
CText(const CText & txt)
{
cout << "CText copy constructor called" << endl;
size_t len{ strlen(txt.pText) + 1 };
pText = new char[len];
strcpy_s(pText, len, txt.pText);
}
CText(CText && txt)
{
cout << "CText move constructor called" << endl;
pText = txt.pText;
txt.pText = nullptr;
}
~CText()
{
cout << "CText destructor called" << endl;
delete[]pText;
}
CText & operator=(const CText & txt)
{
cout << "CText assignment operator function called" << endl;
if (this != &txt)
{
delete[]pText;
size_t length{ strlen(txt.pText) + 1 };
pText = new char[length];
strcpy_s(pText, length, txt.pText);
}
return *this;
}
CText & operator=(CText && txt)
{
cout << "CText move assignment operator function called" << endl;
delete[]pText;
pText = txt.pText;
txt.pText = nullptr;
return *this;
}
CText operator+(const CText & txt)const
{
cout << "CText add operator function called" << endl;
size_t length{ strlen(pText) + strlen(txt.pText) + 1 };
CText aText;
aText.pText = new char[length];
strcpy_s(aText.pText, length, pText);
strcat_s(aText.pText, length, txt.pText);
return aText;
}
};
CText 實現了移動語義的復制構造和賦值運算符函數,並且CText的對象作為CMessage類的成員。
class CMessage
{
private:
CText m_Text;
public:
void showIt()const
{
m_Text.showIt();
}
CMessage operator+(const CMessage & aMess) const
{
cout << "CMessage add operator function called" << endl;
CMessage message;
message.m_Text = m_Text + aMess.m_Text;
return message;
}
CMessage & operator=(const CMessage & aMess)
{
cout << "CMessage assignment operator function called" << endl;
if (this != &aMess)
{
m_Text = aMess.m_Text;
}
return *this;
}
CMessage & operator=(CMessage && aMess)
{
cout << "CMessage move assignment operator function called" << endl;
m_Text = aMess.m_Text;
return *this;
}
CMessage(const char * str = "Default message")//:m_Text{ str }//m_Text { CText(str) }
{
cout << "CMessage constructor called----" << endl;
m_Text = CText(str);
}
CMessage(const CMessage & amess)
{
cout << "cmessage copy constructor called" << endl;
m_Text = amess.m_Text;
}
CMessage(const CMessage && amess)
{
cout << "cmessage move constructor called" << endl;
m_Text = amess.m_Text;
}
};
int main()
{
CMessage motto1{"The devi1 takes care of his own.\n"};
cout << "----------------------------------------" << endl;
CMessage motto2{"if yuo sup with the devil use a long spoon.\n"};
cout << "----------------------------------------" << endl;
CMessage motto3{motto1+motto2};
cout << "----------------------------------------" << endl;
motto3.showIt();
}
注意:CMessage 的構造函數,用初始化列表和在構造函數中初始化的差別。
當用初始化列表的輸出如下: