9.4 派生类中的复制构造函数(1)
记住,复制构造函数是在声明用同类对象初始化的对象时被自动调用的。看一看下面这两条语句:
- CBox myBox(2.0, 3.0, 4.0); // Calls constructor
- CBox copyBox(myBox); // Calls copy constructor
第一条语句调用接受3个double类型实参的构造函数,第二条语句调用复制构造函数。如果我们不提供自定义的复制构造函数,则编译器将提供一个默认的复制构造函数,将初始化对象的成员逐一复制到新对象的对应成员中。为了解执行过程中所发生的事情,我们可以给CBox类添加自定义的复制构造函数版本,然后以CBox类的定义为基础来使用CCandyBox类。
- // Box.h in Ex9_05
- #pragma once
- #include <iostream>
- using std::cout;
- using std::endl;
-
- class CBox // Base class definition
- {
- public:
- // Base class constructor
- CBox(double lv = 1.0, double wv = 1.0, double hv = 1.0):
- m_Length(lv), m_Width(wv), m_Height(hv)
- { cout << endl << "CBox constructor called"; }
-
- // Copy constructor
- CBox(const CBox& initB)
- {
- cout << endl << "CBox copy constructor called";
- m_Length = initB.m_Length;
- m_Width = initB.m_Width;
- m_Height = initB.m_Height;
- }
-
- // CBox destructor - just to track calls
- ~CBox()
- { cout << "CBox destructor called" << endl; }
-
- protected:
- double m_Length;
- double m_Width;
- double m_Height;
- };
我们还记得,为了避免无穷无尽地调用自身,复制构造函数的形参必须被指定为引用,否则将需要复制以传值方式传递的实参。当该示例中的复制构造函数被调用时,将向屏幕上输出一条消息,因此我们从输出中可以看出事件发生的时间。
我们将使用Ex9_04.cpp文件中CCandyBox类的版本,这里再次将其写出:
- // CandyBox.h in Ex9_05
- #pragma once
- #include "Box.h"
- #include <iostream>
- using std::cout;
- using std::endl;
-
- class CCandyBox: public CBox
- {
- public:
- char* m_Contents;
-
- // Derived class function to calculate volume
- double Volume() const
- { return m_Length*m_Width*m_Height; }
-
- // Constructor to set dimensions and contents
- // with explicit call of CBox constructor
- CCandyBox(double lv, double wv, double hv, char* str = "Candy")
- :CBox(lv, wv, hv) // Constructor
- {
- cout << endl <<"CCandyBox constructor2 called";
- m_Contents = new char[ strlen(str) + 1 ];
- strcpy_s(m_Contents, strlen(str) + 1, str);
- }
-
- // Constructor to set contents
- // calls default CBox constructor automatically
- CCandyBox(char* str = "Candy") // Constructor
- {
- cout << endl << "CCandyBox constructor1 called";
- m_Contents = new char[ strlen(str) + 1 ];
- strcpy_s(m_Contents, strlen(str) + 1, str);
- }
-
- ~CCandyBox() // Destructor
- {
- cout << "CCandyBox destructor called" << endl;
- delete[] m_Contents;
- }
- }
这里还没有给CCandyBox类添加复制构造函数,因此我们将依赖编译器生成的版本。