设为首页 加入收藏

TOP

8.6.3 实现CBox类(2)
2013-10-07 12:34:39 来源: 作者: 【 】 浏览:75
Tags:8.6.3 实现 CBox

8.6.3  实现CBox类(2)

2. 合并CBox对象

现在需要解决的问题是重载+、*、/和%运算符,下面依次实现它们。我们已经从Ex8_06.cpp获得的加法操作具有下面的原型:

  1. CBox operator+(const CBox& aBox); // 
    Function adding two CBox objects 

虽然原来实现的加法运算符并不是理想的解决方案,但我们还是要继续使用,以避免使CBox类过于复杂。最好是设计一个程序来检查两个操作数是否有尺寸相同的面,如果有,则顺着这样的面进行连接,但编码工作会很麻烦。当然,如果这是个实际的应用程序,那么我们可以稍后再来开发更好的加法操作,并替换现有的版本,而使用原来版本编写的任何程序都无需修改就能继续运行。类的接口与实现相分离,对于有效的C++(www.cppentry.com)编程(www.cppentry.com)具有决定性意义。

注意,本书不再详述减法运算符。这是个明智的决定,可以避免实现过程中固有的复杂性。如果您实在对此充满热情,而且觉得实现该运算符切合实际,那么可以试一下,但需要决定当得到的体积结果为负数时应做什么事情。如果允许体积为负数,则需要解决哪些箱子的尺寸可以是负数,以及在随后的操作中如何处理这类箱子等问题。

乘法操作非常容易,只是创建一个可包含n个箱子的箱子而已,其中n是乘数。最简单的解决方案是保持对象的m_Length和m_Width不变,然后使高度乘以n从而得到新的CBox对象。我们可以使该函数更智能化一些,那就是检查一下乘数是不是偶数,如果是,则使m_Width加倍,这样箱子将肩并肩堆放,然后只需使m_Height乘以n的1/2即可。该机制如图8-6所示。

 
(点击查看大图)图  8-6
当然,我们不需要检查新对象的长度和宽度哪个更大,因为构造函数会自动将较大的数值挑出来。我们可以将operator*()函数编写成左操作数是CBox对象的成员函数:
  1. // CBox multiply operator this*n  
  2. CBox operator*(int n) const  
  3. {  
  4. if(n % 2)  
  5. return CBox(m_Length, m_Width, n*m_Height);   
  6.         // n odd  
  7. else  
  8. return CBox(m_Length, 2.0*m_Width, (n/2)*m_Height);     // n even  

在这里,我们使用%运算符判断n是偶数还是奇数。如果是奇数,则n % 2的值是1,if语句为true。如果是偶数,则n % 2的值是0,if语句为false。

现在即可使用刚才编写的语句,实现左操作数是整数的版本。我们可以将该函数编写成普通的非成员函数:

  1. // CBox multiply operator n*aBox  
  2. CBox operator*(int n, const CBox& aBox)  
  3. {  
  4. return aBox*n;  

该版本的乘法操作仅仅将操作数的顺序颠倒了一下,这样就可以直接使用前面的乘法运算符版本。至此,为CBox对象定义的算术运算符就全部完成了。最后可以看看如何实现两个分解运算符函数operator/()和operator%()。

3. 分解CBox对象

前面曾经说过,除法操作确定左操作数指定的CBox对象可以包含多少个右操作数指定的CBox对象。为了使问题相对简单,我们假设所有CBox对象都是以正常层序包装的-- 即高度是垂直的,另外假设它们都是以相同的朝向包装的-- 即长度方向相同。如果没有这些假设,问题可能变得相当复杂。

这样,该问题实际上就变为求出一层可以放多少个右操作数对象,再求出左操作数对象中可以放几层。

我们可以将该运算符编写成下面这样的成员函数:

  1. int operator/(const CBox& aBox)  
  2. {  
  3. int tc1 = 0;                // Temporary for number 
    in horizontal plane this way  
  4. int tc2 = 0;                // Temporary for number 
    in a plane that way  
  5.  
  6. tc1 = static_cast<int>((m_Length / aBox.m_Length))*  
  7. static_cast<int>((m_Width / aBox.m_Width)); // to fit this way  
  8.  
  9. tc2 = static_cast<int>((m_Length / aBox.m_Width))*  
  10. static_cast<int>((m_Width / aBox.m_Length)); // and that way  
  11.  
  12. //Return best fit  
  13. return static_cast<int>((m_Height/aBox.m_Height)*(tc1>tc2   tc1 :   
  14. tc2));  

该函数首先求出左、右操作数CBox对象的长度方向相同时,一层可以容纳多少个右操作数CBox对象,并将结果存入tc1。然后再求出右操作数CBox的长度与左操作数CBox的宽度同向时,一层可以容纳多少个右操作数对象。最后,使tc1和tc2中较大的数乘以可以包装的层数,并返回得到的数值。该过程如图8-7所示。

我们看到有两种将bBox放入aBox的可能性:一是bBox的长度与aBox的长度同向,二是bBox的长度与aBox的宽度同向。从图8-7可以看出,最好的包装方式是旋转bBox,用它的宽度去除aBox的长度。

 
(点击查看大图)图  8-7
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇8.6.3 实现CBox类(3) 下一篇8.1.1 析构函数的概念

评论

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