【C++】深浅コピー実装Stringクラス
5981 ワード
深浅コピーとは?
文字列char*str 1=「hello」を定義します.
文字列char*str 2とstr 1を定義するデータは同じで、この場合は2つに分けられます. str 1とstr 2のデータと空間は同じであり、str 2はstr 1のアドレス空間を指す. str 2は別の空間を開き、str 1のデータをstr 2にコピーします.すなわち、str 1とstr 2のデータは同じで、指向するアドレスは違います.
1つ目は浅いコピー、2つ目は深いコピーと呼ばれます
C++では、浅いコピーを使用すると深刻なコード事故が発生しやすい---メモリ漏れ
str 1とstr 2は同じアドレス空間を指し、構造関数はシステムが自動的に生成して呼び出され、空き構造が2回発生する場合がある.
次に、濃淡コピーの伝統的な書き方と現代的な書き方を用いてStringクラスを実現します.
従来の書き方と現代の書き方の主な違いは、コピー構造関数と賦値オペレータのリロード関数の書き方が異なることであり、以下の通りである.
コピーコンストラクション関数の書き方:
代入演算子のリロード関数の異なる書き方:
すべてのコード実装:
文字列char*str 1=「hello」を定義します.
文字列char*str 2とstr 1を定義するデータは同じで、この場合は2つに分けられます.
1つ目は浅いコピー、2つ目は深いコピーと呼ばれます
C++では、浅いコピーを使用すると深刻なコード事故が発生しやすい---メモリ漏れ
str 1とstr 2は同じアドレス空間を指し、構造関数はシステムが自動的に生成して呼び出され、空き構造が2回発生する場合がある.
次に、濃淡コピーの伝統的な書き方と現代的な書き方を用いてStringクラスを実現します.
従来の書き方と現代の書き方の主な違いは、コピー構造関数と賦値オペレータのリロード関数の書き方が異なることであり、以下の通りである.
コピーコンストラクション関数の書き方:
void Swap(String& s)
{
swap(_str,s._str);
swap(_size,s._size);
swap(_capacity,s._capacity);
}
//
String(const String& s)
:_str(new char[strlen(s._str)+1])
{
strcpy(_str,s._str);
}
//
String(const String& s)
:_str(NULL)
{
String tmp(s._str);
Swap(tmp);
}
代入演算子のリロード関数の異なる書き方:
String& operator=(const String& s){
if(this!=&s){
String tmp(s._str);
swap(_str,tmp._str);
}
return *this;
}
String& operator=(String s){
if(this!=&s){
Swap(s);
return *this;
}
}
//
//s1=s2,s2 s1
// , ,
//
String& operator=(const String& s)
{
if(this!=&s){
delete[] _str;
char* tmp=new char[strlen(s._str)+1];
strcpy(tmp,s._str);
_str=tmp;
}
return *this;
}
すべてのコード実装:
#pragma once
#include
#include
#include
using namespace std;
//1.
//2.
class String{
public:
String(const char* str)
:_size(strlen(str))
,_capacity(_size)
{
_str=new char[_size+1];
strcpy(_str,str);
}
void Swap(String& s)
{
swap(_str,s._str);
swap(_size,s._size);
swap(_capacity,s._capacity);
}
//s1(s);
String(const String& s)
:_str(new char[strlen(s._str)+1])
{
strcpy(_str,s._str);
}
//
/* String(const String& s)
:_str(NULL)
{
String tmp(s._str);
Swap(tmp);
}
String& operator=(const String& s){
if(this!=&s){
String tmp(s._str);
swap(_str,tmp._str);
}
return *this;
}*/
String& operator=(String s){
if(this!=&s){
Swap(s);
return *this;
}
}
//s1=s2,s2 s1
// , ,
//
/*String& operator=(const String& s)
{
if(this!=&s){
delete[] _str;
char* tmp=new char[strlen(s._str)+1];
strcpy(tmp,s._str);
_str=tmp;
}
return *this;
}
*/
~String(){
if(_str){
delete[] _str;
_str=NULL;
}
}
void Expand(size_t n){
if(n>_capacity){
char* tmp=new char[n+1];
strcpy(tmp,_str);
delete[] _str;
_str=tmp;
_capacity=n;
}
}
void PushBack(char ch){
if(_size>=_capacity){
Expand(2*_size);
}
_str[_size]=ch;
_str[_size+1]='\0';
++_size;
}
void Append(const char* str){//
size_t len=strlen(str);
if(_size+len>=_capacity){
Expand(_size+len);
}
strcpy(_str+_size,str);
_size+=len;
}
void PopBack()
{
assert(_size);
_str[_size--]='\0';
--_size;
}
void Insert(size_t pos,char ch){
assert(pos<=_size);
if(_capacity==_size){
Expand(2*_capacity);
}
size_t end=_size;
while(end>=pos){
_str[end+1]=_str[end];
--end;
}
_str[pos]=ch;
++_size;
}
void Insert(size_t pos,const char* str){
assert(pos<=_size);
int len=strlen(str);
if(_size+len>_capacity){
Expand(_size+len);
}
for(int i=pos;i<_size _str="" for="" j="0;j<len;j++){" void="" erase="" pos="" n="" assert="" if="" strcpy="" size_t="" size="" return="" _size="" capacity="" _capacity="" bool="" empty="" char="" operator="" find="" ch="" count="0;" i="0;i<_size;i++){" str="" src="_str;" while="" const="" dest="str;" string="" tmp="" tmp.pushback="" this-="">PushBack(ch);
return *this;
}
//s1+=s2
String operator+=(const String& str){
*this+=str._str;//s._str , operator+=
return *this;
}
String operator+(const char* str){
assert(str);
String tmp(*this);
tmp.Append(str);
return tmp;
}
String& operator+=(char* str){
this->Append(str);
return *this;
}
int _strcmp(const char* str1,const char* str2){
while(*str1&&*str2){
if(*str1>*str2){
return 1;
}else if(*str1(const String& s)
{
if((_strcmp(_str,s._str))>0){
return true;
}else{
return false;
}
}
bool operator>=(const String& s)
{
if((_strcmp(_str,s._str))>=0){
return true;
}else{
return false;
}
}
// C
char* c_str(){
return _str;
}
private:
char* _str;
size_t _size;
size_t _capacity;
};
void TestString(){
String s1("hello");
// cout<