8.4.4 重载加法运算符(1)
本节将介绍如何为CBox类重载加法运算符。这是个有趣的问题,因为涉及创建和返回新的对象。新对象是两个操作数(两个CBox对象)的和(无论将和的意义定义成什么)。
那么,我们真正希望两个箱子的和是什么?关于这一点有很多合法的可能性,但我们在这里将力求简单。下面这样定义两个CBox对象的和:它是个CBox对象,其体积足够容纳这两个摞在一起的箱子。理想情况下,可通过把两个箱子的最短尺寸合并起来将它们连接起来。为此,可以确保箱子的长度总是大于或等于宽度,且箱子的宽度总是大于或等于高度。接着使新对象的m_Length成员等于两个相加对象中较大的m_Length成员,并以类似的方式求出m_Width成员,然后使m_Height成员等于两个操作数对象的m_Height成员的和,即可使合成的CBox对象足以包含这两个CBox对象。这种实现方法未必是最优的解决方案,因为两个箱子可以绕着高度轴旋转,得到更有效的合并方式,但就我们的目的而言已经足够。通过修改构造函数,还将使CBox对象的长度、宽度和高度按降序排列。
CBox类的加法运算符版本更容易通过图形来解释,因此在图8-4中阐明了相加的过程。

因为需要访问CBox对象的私有成员,所以应该将operator+()实现为该类的成员函数。该函数成员在类定义内部的声明如下所示:
- CBox operator+(const CBox& aBox) const; // Function adding two CBox objects
我们将形参定义成引用,以避免调用该函数时不必要地复制右边的实参。我们还将形参声明为const引用,因为该函数不修改实参。如果不把形参声明为const引用,则编译器不允许将const对象传递给这个函数,因此+运算符的右操作数不可以是const CBox对象。我们将该运算符函数也声明为const,因为它不修改调用它的那个对象。如果不这样做,则+运算符的左操作数也不可以是const CBox对象。
operator+()函数的定义现在如下所示:
- // Function to add two CBox objects
- CBox CBox::operator+(const CBox& aBox) const
- {
- // New object has larger length and width, and sum of heights
- return CBox(m_Length > aBox.m_Length m_Length : aBox.m_Length,
- m_Width > aBox.m_Width m_Width : aBox.m_Width,
- m_Height + aBox.m_Height);
- }
根据当前对象(*this)和传递的实参对象aBox,我们构造出一个局部的CBox对象。记住,返回过程将创建局部对象的临时副本,并将此副本(而非从函数返回时将被抛弃的局部对象)返回给调用程序。
试一试:练习使用重载的加法运算符
在这个示例中,我们将能够看到CBox类中重载加法运算符的工作过程。
- // Ex8_06.cpp
- // Adding CBox objects
- #include <iostream> // For stream I/O
- #include <utility> // For operator overload templates
- using std::cout;
- using std::endl;
- using namespace std::rel_ops;
- class CBox // Class definition at global scope
- {
- public:
- // Constructor definition
- explicit CBox(double lv = 1.0, double wv = 1.0, double hv = 1.0): m_Height(hv)
- {
- m_Length = std::max(lv, wv);
- m_Width = std::min(lv, wv);
- // Length is now greater than or equal to width
- if(m_Height > m_Length)
- {
- m_Height = m_Length;
- m_Length = hv;
- // m_Height is still greater than m_Width so swap them
- double temp = m_Width;
- m_Width = m_Height;
- m_Height = temp;
- }
- else if( m_Height > m_Width)
- {
- m_Height = m_Width;
- m_Width = hv;
- }
- }
- // Function to calculate the volume of a box
- double Volume() const
- {
- return m_Length*m_Width*m_Height;
- }
- // Operator function for 'less than' that
- // compares volumes of CBox objects.
- bool operator<(const CBox& aBox) const
- {
- return this->Volume() < aBox.Volume();
- }
- // 'Less than' operator function to compare a CBox object volume with a constant
- bool operator<(const double& value) const
- {
- return this->Volume() < value;
- }
- // 'Greater than' function to compare a CBox object volume with a constant
- bool operator>(const double& value) const
- {
- return this->Volume() > value;
- }
- // Overloaded equality operator
- bool operator==(const CBox& aBox) const
- {
- return this->Volume() == aBox.Volume();
- }
- // Function to add two CBox objects
- CBox operator+(const CBox& aBox) const
- {
- // New object has larger length & width, and sum of heights
- return CBox(m_Length > aBox.m_Length m_Length : aBox.m_Length,
- m_Width > aBox.m_Width m_Width : aBox.m_Width,
- m_Height + aBox.m_Height);
- }
- // Function to show the dimensions of a box
- void ShowBox() const
- {
- cout << m_Length << " " << m_Width << " " << m_Height << endl;
- }
- private:
- double m_Length; // Length of a box in inches
- double m_Width; // Width of a box in inches
- double m_Height; // Height of a box in inches
- };
- // Function comparing a constant with a CBox object
- inline bool operator>(const double& value, const CBox& aBox)
- {
- return value > aBox.Volume();
- }
- int main()
- {
- CBox smallBox(4.0, 2.0, 1.0);
- CBox mediumBox(10.0, 4.0, 2.0);
- CBox aBox;
- CBox bBox;
- cout << "smallBox dimensions are ";
- smallBox.ShowBox();
- cout << "mediumBox dimensions are ";
- mediumBox.ShowBox();
- aBox = smallBox + mediumBox;
- cout << "aBox = smallBox + mediumBox. Dimensions are "
- aBox.ShowBox();
- bBox = aBox + smallBox + mediumBox;
- cout << "bBox = aBox + smallBox + mediumBox. Dimensions are "
- bBox.ShowBox();
- return 0;
- }