您好,登錄后才能下訂單哦!
c++的動態內存管理是非常重要的,操作不當很容易引起內存泄漏,
下面我詳細寫了一些內存管理該注意的地方,包括引用計數的實現
深拷貝淺拷貝
#include <iostream>
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 <iostream>
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 <iostream>
#include<windows.h>
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; //指向引用計數的指針
};
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。