For a long time did not write C + +, today wrote a very simple string class, unexpectedly debugging a half-day, finally found a very hidden trap, write out for everyone to share.
The function of a copy constructor for a class in C + + is to instantiate another object from one object of the class. Here is a mystring class I wrote, the header file MyString.h:
#include <iostream>using namespace Std;class mystring{public:mystring (); MyString (const mystring& str);//Here is where we study MyString (char *p); ~mystring (); Friend ostream& operator<< ( ostream& out,mystring& ms) {return out<< "M_data=" <<ms.m_data;} Private:int m_length;char* m_data;//Note here is a pointer, not an array};
Take a look at the implementation version of the first class:
#include <cstring> #include "MyString.h" using namespace std; Mystring::mystring (): M_length (1), m_data (new Char[m_length]) {memcpy (M_data, "", M_length);} mystring::mystring (const mystring& str): M_length (Str.m_length), m_data (new char [m_length])//used here is new char[], In addition, here the M_length and m_data initialization order can not be changed, the reason for their own to know {memcpy (m_data,str.m_data,m_length);} Mystring::mystring (char *p): M_length (strlen (p) +1), m_data (new Char[m_length]) {memcpy (m_data,p,m_length);} Mystring::~mystring () {//note here; Delete [] m_data;}
use a simple example to test (test.cpp):
#include "MyString.h" #include <iostream>using namespace Std;int main () {MyString B ("Backup"); MyString A (b); Cout<<a<<endl;}
the results are familiar to everyone.
Take a look at the second implementation version of the MyString class (MyString.cpp)
#include <cstring> #include "MyString.h" using namespace std; Mystring::mystring (): M_length (1), m_data (new Char[m_length]) {memcpy (M_data, "", M_length);} mystring::mystring (const mystring& str): M_length (Str.m_length), m_data (str.m_data)//Copy the pointer directly here; {//memcpy (m_data,str.m_data,m_length);} Mystring::mystring (char *p): M_length (strlen (p) +1), m_data (new Char[m_length]) {memcpy (m_data,p,m_length);} Mystring::~mystring () {//note here; Delete [] m_data;}
The result of the operation is:
The reason is actually very simple, set a breakpoint debugging a bit to know.
In the second version, we copied the pointer directly, and then the output did not have a problem ("M_data=backup"), and according to the copy constructor, objects A and B both point to the same character array, after the destructor of B, the memory space of the character array is gone, and then a destructor is executed. Delete the memory space that does not exist and there will be an error.
Summary sentence: C + + is really worthy of one of the most difficult programming language, errors are more difficult to find and generally unexpected.
C + + class copy Construction (copy constructor) function hidden traps