通过cstring的处理进行熟悉知识点:
在进行赋值构造和复制构造时,主要涉及到对象的深拷贝和浅拷贝。
计算机默认是进行浅拷贝(有关构造函数中执行申请内存相关的变量,浅拷贝会拷贝地址而不是真正申请内存,会导致析构释放不匹配),涉及到相关的内存问题时,我们要注意自己对内存做处理,实现一些内存的申请和拷贝。
也可以使用delete关键字或者类的private特性禁用拷贝构造和赋值构造。
#include <stdio.h> #include <stdlib.h> #include <string.h> class MyString{ public: //构造函数 析构函数 拷贝构造函数 赋值构造函数 MyString() { mystr = NULL; } ~MyString() { if(mystr != NULL) { free(mystr); mystr = NULL; } } //= NULL是没有参数和上面冲突了 MyString(const char* cstr ); MyString(const MyString &s); MyString &operator=( const MyString &str); void Print() { printf("%s \n", mystr); } private: char* mystr = NULL; //成员变量一定要注意初始化,在这里或者构造函数后面 }; MyString::MyString(const char* cstr) { if(cstr == NULL) { mystr= NULL; // mystr = (char*)malloc(1);//申请内存过小,可能导致踩内存 // mystr[0] = '\0'; return ; } mystr = (char*)malloc((int)strlen(cstr)+1); memset(mystr, 0 , (int)strlen(cstr)+1); memcpy(mystr, cstr, (int)strlen(cstr)+1); } MyString::MyString(const MyString &s) { if(this == &s) { return; } if(mystr != NULL) { free(mystr); } mystr = (char*)malloc((int)strlen(s.mystr)+1); memset(mystr, 0 , (int)strlen(s.mystr)+1); memcpy(mystr, s.mystr, (int)strlen(s.mystr)+1); } // CMyString & CMyString::operator = (const CMyString& cstr) // { // //if(*this != cstr) // if(this == &cstr) // { // CMyString strtemp (cstr); // char * pTemp = temp.m_cstr; //这个应该是不合理的 // strtemp.m_cstr = m_cstr; //析构的时候会自动释放这个内存 // m_cstr = pTemp; //替换了内存的指向 // } // return *this; // } MyString & MyString::operator=( const MyString &str) { if(this == &str) { return *this; } if(mystr != NULL) { free(mystr); } mystr = (char*)malloc((int)strlen(str.mystr)+1); memset(mystr, 0 , (int)strlen(str.mystr)+1); memcpy(mystr, str.mystr, (int)strlen(str.mystr)+1); return *this; } int main() { MyString str("123"); str.Print(); MyString str1 = "1233"; str1.Print(); //有问题的 MyString str2(str1); str2.Print(); //有问题的 CMyString str3 = str; MyString str3 ; str3 = str; str3.Print(); MyString str4; MyString str5; str4 = str5 = str2; str4.Print(); str5.Print(); return 0; }