通过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;
}