8.5.1 避免不必要的复制操作(1)
通过修改Ex8_05.cpp的CMessage类,我们来看看如何避免不必要的复制操作。下面是CMessage类实现相加运算符之后的版本。
- class CMessage
- {
- private:
- char* pmessage; // Pointer to object text string
- public:
- // Function to display a message
- void ShowIt() const
- {
- cout << endl << pmessage;
- }
- // Overloaded addition operator
- CMessage operator+(const CMessage& aMess) const
- {
- cout << "Add operator function called." << endl;
- size_t len = strlen(pmessage) + strlen(aMess.pmessage) + 1;
- CMessage message;
- message.pmessage = new char[len];
- strcpy_s(message.pmessage, len, pmessage);
- strcat_s(message.pmessage, len, aMess.pmessage);
- return message;
- }
- // Overloaded assignment operator for CMessage objects
- CMessage& operator=(const CMessage& aMess)
- {
- cout << "Assignment operator function called." << endl;
- if(this != &aMess) // Check addresses are not equal
- {
- // Release memory for 1st operand
- delete[] pmessage;
- pmessage = new char[strlen(aMess.pmessage) + 1];
- // Copy 2nd operand string to 1st
- strcpy_s(this->pmessage, strlen(aMess.pmessage)+1, aMess.pmessage);
- }
- return *this; // Return a reference to 1st operand
- }
- // Constructor definition
- CMessage(const char* text = "Default message")
- {
- cout << "Constructor called." << endl;
- pmessage = new char[strlen(text) + 1]; // Allocate space for text
- strcpy_s(pmessage, strlen(text)+1, text); // Copy text to new memory
- }
- // Copy constructor definition
- CMessage(const CMessage& aMess)
- {
- cout << "Copy constructor called." << endl;
- size_t len = strlen(aMess.pmessage)+1;
- pmessage = new char[len];
- strcpy_s(pmessage, len, aMess.pmessage);
- }
- // Destructor to free memory allocated by new
- ~CMessage()
- {
- cout << "Destructor called." // Just to track what happens
- << endl;
- delete[] pmessage; // Free memory assigned to pointer
- }
- };
对Ex8_05.cpp版本所做的修改采用突出显示。现在从构造函数和赋值运算符函数的输出,来跟踪何时调用它们。此类中还有一个复制构造函数和一个operator+()函数。operator+()函数用来将两个CMessage对象加起来。我们可以添加将CMessage对象用字符串字面量连接起来的版本,但根据目前的用途,没必要这么做。通过CMessage对象上的一些简单操作,来看看复制时都发生了些什么。
试一试:跟踪对象的复制操作
下面的代码用来练习CMessage类:
- // Ex8_07.cpp
- // How many copy operations
- #include <iostream>
- #include <cstring>
- using std::cout;
- using std::endl;
- // Insert CMessage class definition here...
- int main()
- {
- CMessage motto1("The devil takes care of his own. ");
- CMessage motto2("If you sup with the devil use a long spoon.\n");
- CMessage motto3;
- cout << " Executing: motto3 = motto1 + motto2 " << endl;;
- motto3 = motto1 + motto2;
- cout << " Done!! " << endl << endl;
- cout << " Executing: motto3motto3 = motto3 + motto1 + motto2 " << endl;
- motto3motto3 = motto3 + motto1 + motto2;
- cout << " Done!! " << endl << endl;
- cout << "motto3 contains - ";
- motto3.ShowIt();
- cout << endl;
- return 0;
- }