移动语义 && 函数调用过程中的 …
2018-06-17 23:40:20来源:未知 阅读 ()
当以一个函数内的临时变量对象作为另一个函数的形参的时候,原函数内的临时对象即 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 的构造函数,用初始化列表和在构造函数中初始化的差别。
当用初始化列表的输出如下:
:m_Text { CText(str) }
CText constructor called
CMessage constructor called
----------------------------------------
CText constructor called
CMessage constructor called
----------------------------------------
CMessage add operator function called
CText constructor called
CMessage constructor called
CText add operator function called
CText constructor called
CText move constructor called
CText destructor called
CText move assignment operator function called
CText destructor called
CText constructor called
cmessage copy constructor called
CText assignment operator function called
CText destructor called
----------------------------------------
The devi1 takes care of his own.
if yuo sup with the devil use a long spoon.
CText destructor called
CText destructor called
CText destructor called
用思维把运行过程走一遍,会发现红色部分出现问题(rvalue 被函数当成 lvalue 使用)。
也许你会疑惑临时变量的生成等操作,并没有输出,因为它们是编译器暗地做的工作。就像按值传递一样,我们也一无所知。
方法:
若想要避免我们所看到的红色标记问题,使用移动语义就可以 std:move() 。
CMessage(const CMessage && amess)
{
cout << "cmessage move constructor called" << endl;
m_Text = std::move(amess.m_Text);
}
CMessage & operator=(CMessage && aMess)
{
cout << "CMessage move assignment operator function called" << endl;
// m_Text = std::move(aMess.m_Text);
m_Text = static_cast<CText &&>(aMess.m_Text); //和 std:move() 功能一样,属于强制转换
return *this;
}
问题再描述:
如果我们已经按如上方式做了努力,而 CMessage & operator=( const CMessage && aMess),使用了 const ,使用移动语义也是没了效果。
这属于 const 类型函数,调用 const 函数问题。
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- Unsolved --> Solved OJ思路题解 2020-05-30
- Building & Debugging chromium on CLion for Linu 2020-05-19
- 洛谷P1164->小A点菜 2020-05-18
- 表达式·表达式树·表达式求值 2020-04-29
- STL之<string> 2020-04-05
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash