设为首页 加入收藏

TOP

8.5.3 命名的对象是lvalue(2)
2013-10-07 16:09:20 来源: 作者: 【 】 浏览:83
Tags:8.5.3 命名 对象 lvalue

8.5.3  命名的对象是lvalue(2)

看起来似乎有很多代码,这是因为CText类具有重载的复制构造函数和赋值运算符版本,并定义了operator+()函数。CMessage类在实现自己的成员函数时使用了它们。同时还用输出语句来跟踪何时调用了每个函数。下面通过一个示例来练习这些类的用法。

试一试:重新导致效率低下

下面是一个简单的main()函数,它使用CMessage类的复制构造函数和赋值运算符:

  1. // Ex8_09.cpp Creeping inefficiencies  
  2. #include <iostream> 
  3. #include <cstring> 
  4. using std::cout;  
  5. using std::endl;  
  6. // Insert CText class definition here...  
  7. // Insert CMessage class definition here...  
  8. int main()  
  9. {  
  10. CMessage motto1("The devil takes care of his own. ");  
  11. CMessage motto2("If you sup with the devil use a long spoon.\n");  
  12. cout << endl << " Executing: CMessage motto3(motto1+motto2); " << endl;  
  13. CMessage motto3(motto1+motto2);  
  14. cout << " Done!! " << endl << endl << "motto3 contains - ";  
  15. motto3.ShowIt();  
  16. CMessage motto4;  
  17. cout << endl << " Executing: motto4 = motto3 + motto2; " << endl;  
  18. motto4 = motto3 + motto2;  
  19. cout << " Done!! " << endl << endl << "motto4 contains - ";  
  20. motto4.ShowIt();  
  21. cout << endl;  
  22. return 0;  
  23. }  

示例说明

main()函数中相对很少的语句却产生了很多输出。我们只讨论几个有意思的地方。首先考虑执行下面这条语句产生的输出:

  1. CMessage motto3(motto1+motto2); 

输出如下所示:

  1. CMessage add operator function called.  
  2. CText constructor called.  
  3. CMessage constructor called.  
  4. CText constructor called.  
  5. CText move assignment operator function called.  
  6. CText destructor called.  
  7. CText add operator function called.  
  8. CText constructor called.  
  9. CText move copy constructor called.  
  10. CText destructor called.  
  11. CText move assignment operator function called.  
  12. CText destructor called.  
  13. CText constructor called.  
  14. CMessage move constructor called.  
  15. CText assignment operator function called.  
  16. CText destructor called.  

要了解到底发生了些什么事,需要将输出消息与被调用函数中的代码关联起来。首先调用CMessage类的operator+()函数,将motto1与motto2连接起来。在operator+()函数体内,调用CMessage构造函数来创建消息对象,在此过程中,调用CText构造函数。一切进行得很顺利,直到到达输出的倒数第二行,即表明调用CMessage移动构造函数的那行输出后面。当此构造函数执行时,实参必须是临时的(即一个rvalue),因此,函数体中存储text成员值的赋值语句应该是CText对象的一个移动赋值操作,而不是复制赋值操作。于是问题就出现了,因为在CMessage移动构造函数内,aMess形参是一个lvalue(因为它有名称),尽管事实上我们肯定知道传递给函数的实参是一个rvalue。这就意味着aMess.text也是一个lvalue。如果不是,则会调用CMessage复制构造函数。

下面这条语句也会产生同样的问题:

  1. motto4 = motto3 + motto2; 

如果看一下这条语句的输出,就会发现当调用CMessage对象的移动赋值运算符时会产生完全相同的问题。当实际上可以移动实参的text成员时,却对它进行了复制。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇8.5.3 命名的对象是lvalue(1) 下一篇8.5.3 命名的对象是lvalue(3)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·python数据分析岗的 (2025-12-25 10:02:21)
·python做数据分析需 (2025-12-25 10:02:19)
·成为一个优秀的pytho (2025-12-25 10:02:16)
·Java后端面试实习自 (2025-12-25 09:24:21)
·Java LTS版本有哪些 (2025-12-25 09:24:18)