先看示例代碼
創(chuàng)新互聯(lián)公司成都網(wǎng)站建設(shè)按需開發(fā),是成都網(wǎng)站開發(fā)公司,為成都會所設(shè)計提供網(wǎng)站建設(shè)服務(wù),有成熟的網(wǎng)站定制合作流程,提供網(wǎng)站定制設(shè)計服務(wù):原型圖制作、網(wǎng)站創(chuàng)意設(shè)計、前端HTML5制作、后臺程序開發(fā)等。成都網(wǎng)站設(shè)計熱線:028-86922220
#include
#include
using namespace std;
class Student{
public:
Student(int _age , const char * _name)
{
this->age=_age;
int len=strlen(_name)+1;
char *tep=new char[len];
this->pName=tep;
strcpy(this->pName,_name);
}
~Student(){
delete[]this->pName;
this->pName=nullptr;
}
void showStudent(){
cout<pName<<" "<age<
上面示例代碼中,對象的默認拷貝方式是內(nèi)存數(shù)據(jù)拷貝,如果對象占用了外部資源,那么就會出現(xiàn)問題了,這里的外部資源
就是在堆上申請的空間存放名字用,
s1,s2兩個對象中的名字指針都是指向了同一塊堆內(nèi)存區(qū)域,在結(jié)束main函數(shù)的是,s2先析構(gòu),s2會析構(gòu)調(diào)堆上的內(nèi)存空間,
s1再析構(gòu),由于s1對象的pName 指針和s2對象的pName指針指向的是同一塊堆內(nèi)存區(qū)域,但是該區(qū)域內(nèi)存已經(jīng)被釋放了,所以遇到了問題
鑒于上面的問題,我們引出了 淺拷貝,深拷貝的問題和解決方法.
Student s2=s1; 會調(diào)用拷貝構(gòu)造函數(shù)(該拷貝構(gòu)造函數(shù)可以是系統(tǒng)自動生成的,或者你自己定義一個拷貝構(gòu)造函數(shù))
系統(tǒng)自動生成的拷貝構(gòu)造函數(shù)做的是內(nèi)存數(shù)據(jù)拷貝,所以就出現(xiàn)了上面的問題.因此我們需要定義屬于自己的拷貝構(gòu)造函數(shù)
改造代碼如下
class Student2{
public:
Student2(int _age , const char * _name)
{
this->age=_age;
int len=strlen(_name)+1;
char *tep=new char[len];
this->pName=tep;
strcpy(this->pName,_name);
cout<<"執(zhí)行構(gòu)造函數(shù)"<age=_stu2.age;
int len =strlen(_stu2.getPName())+1;
char *newPName =new char[len];
this->pName=newPName;
strcpy(this->pName,_stu2.getPName());
cout<<"執(zhí)行拷貝構(gòu)造函數(shù)"<pName!=nullptr){
delete[]this->pName;
this->pName=nullptr;
}
}
void showStudent(){
int *p=(int *)this->pName;
cout<pName<<" "<age<<" pName Heap Address ="<pName;
}
private:
int age;
char *pName;
};
int main(){
Student2 s1(20,"zhangsan");
s1.showStudent();
Student2 s2=s1;
s2.showStudent();
return 1;
}
上面的代碼還存在一個問題如下,如果在main函數(shù)中是下面的代碼
Student2 s1(20,"zhangsan");
Student2 s2(30,"lisi");
s2=s1;
在main函數(shù)結(jié)束的是同樣會遇到問題,這個時候就引出 賦值函數(shù),我們需要定義自己的賦值函數(shù)
在 s2=s1這一段代碼其實是這樣調(diào)用的
s2.operator=(s1)
在你不定義自己的賦值函數(shù)的時候,系統(tǒng)會幫我們生成一個賦值函數(shù),該賦值函數(shù)的賦值方式就是內(nèi)存的數(shù)值拷貝,這種方式
在Student對象,會有問題,所以我們需要向自定義拷貝構(gòu)造一樣,定義一個屬于自己的賦值函數(shù)
代碼如下
class Student3{
public:
Student3(int _age , const char * _name)
{
this->age=_age;
int len=strlen(_name)+1;
char *tep=new char[len];
this->pName=tep;
strcpy(this->pName,_name);
cout<<"執(zhí)行構(gòu)造函數(shù)"<age=_stu.age;
int len =strlen(_stu.getPName())+1;
char *newPName =new char[len];
this->pName=newPName;
strcpy(this->pName,_stu.getPName());
cout<<"執(zhí)行拷貝構(gòu)造函數(shù)"<pName;
this->age=_stu.age;
int len =strlen(_stu.getPName())+1;
char *newPName =new char[len];
this->pName=newPName;
strcpy(this->pName,_stu.getPName());
cout<<"執(zhí)行賦值函數(shù)"<pName!=nullptr){
delete[]this->pName;
this->pName=nullptr;
}
}
void showStudent(){
int *p=(int *)this->pName;
cout<pName<<" "<age<<" pName Heap Address ="<pName;
}
private:
int age;
char *pName;
};
int main(){
Student3 s3(20,"zhangsan");
s3.showStudent();
Student3 s4(30,"lisi");
s4=s3;
s4.showStudent();
return 1;
}
運用深拷貝淺拷貝實現(xiàn)String 代碼如下
#include
#include
using namespace std;
class MyString{
public:
//構(gòu)造函數(shù)
MyString(const char * src){
//創(chuàng)建空串
if(src==nullptr){
this->pchar=new char[1];
this->pchar[0]='\0';
}
else{
int len =strlen(src)+1;
this->pchar=new char[len];
strcpy(this->pchar,src);
}
cout<<"執(zhí)行構(gòu)造函數(shù), 堆內(nèi)存空間地址"<<(int *)this->pchar <pchar=new char[len];
strcpy(this->pchar,myString.pchar);
cout<<"執(zhí)行拷貝構(gòu)造函數(shù), 新創(chuàng)建堆內(nèi)存空間地址"<<(int *)this->pchar <pchar;
this->pchar=nullptr;
int len =myString.stringLen()+1;
this->pchar=new char[len];
strcpy(this->pchar,myString.pchar);
cout<<"執(zhí)行賦值函數(shù), 新創(chuàng)建堆內(nèi)存空間地址"<<(int *)this->pchar <pchar);
}
//析構(gòu)
~MyString(){
delete [] this->pchar;
this->pchar=nullptr;
}
void printChar() const{
cout<pchar<