大橙子网站建设,新征程启航
为企业提供网站建设、域名注册、服务器等服务
c++的动态内存管理是非常重要的,操作不当很容易引起内存泄漏,
我们提供的服务有:成都网站设计、成都网站制作、微信公众号开发、网站优化、网站认证、可克达拉ssl等。为上千家企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的可克达拉网站制作公司
下面我详细写了一些内存管理该注意的地方,包括引用计数的实现
深拷贝浅拷贝
#include
using namespace std;
class String
{
public:
String()
:_str(new char[1])
{
*_str = '\0';
}
String(char* str)
:_str(new char[strlen(str)+1]) //开辟一段新空间给_str
{
strcpy(_str, str);
}
//上面两个构造函数可以合成下面一个
String(char* str="")
:_str(new char[strlen(str) + 1]) //开辟一段新空间给_str
{
strcpy(_str, str);
}
String(const String& s)//拷贝构造
:_str(new char[strlen(s._str) + 1]) //开辟一段新空间给_str,也就是深拷贝,使他们指向不同的空间
{
strcpy(_str, s._str);
}
String& operator=(const String& s)
{
if (this != &s)
{
delete[] _str;//这里一定要注意,很容易发生内存泄露,因为原来s3就有一段空间,赋值时
//使s3重新指向一段空间,原来的空间就泄露了。
_str = new char[strlen(s._str) + 1];
strcpy(_str, s._str);
}
return *this;
}
~String()
{
if (_str)
{
delete[]_str;
}
}
char* GetStr()
{
return _str;
}
char& operator[](size_t index) //改变字符串内容
{
return _str[index];
}
private:
char *_str;
};
void Test1()
{
char* p1 = "abcd";
String s1(p1);
cout << s1.GetStr() << endl;
s1[0] = 'x';
cout << s1.GetStr() << endl;
//浅拷贝
String s2(s1);//没有写自己的拷贝构造函数时,用系统默认的拷贝构造,是值拷贝,s1和s2指向同一块空间一模一样,析构时
//会析构两次,导致崩溃
String s3("efgh");
s3 = s1; //需要重载赋值运算符
s3 = s3;
}
int main()
{
Test1();
return 0;
}
#include
using namespace std;
class String
{
public:
String(char* str = "")
:_str(new char[strlen(str) + 1])
{
strcpy(_str, str);
}
String(const String& s)
:_str(NULL)
{
String tmp(s._str);
swap(_str, tmp._str);
}
//String& operator=(String& s)
//{
// if (this != &s)
// {
// String tmp(s);
// swap(_str, tmp._str);
// }
// return *this;
//}
String& operator=(String s)
{
swap(_str, s._str);
return *this;
}
~String()
{
if (_str)
{
delete[] _str;
}
}
private:
char* _str;
};
void Test1()
{
char* p1 = "abcd";
String s1(p1);
String s2(s1);
String s3("efgh");
s3 = s1;
s3 = s3;
}
int main()
{
Test1();
return 0;
}
//引用计数相关操作
#include
#include
using namespace std;
class String
{
public:
String(char* str = "")
:_str(new char[strlen(str) + 1])
, _pCount(new int(1))
{
strcpy(_str, str);
}
String(const String& s)
:_str(s._str)
, _pCount(s._pCount)
{
(*_pCount)++;
}
String& operator=(const String& s)
{
if (this != &s)
{
this->_Release();
_str = s._str;
_pCount = s._pCount;
(*_pCount)++;
}
return *this;
}
~String()
{
_Release();
}
private:
void _Release()
{
if (--(*_pCount) == 0)
{
delete _pCount;
delete[] _str;
}
}
private:
char* _str;
int* _pCount; //指向引用计数的指针
};