[置顶] 运算符重载,浅拷贝(logical copy) ,vs, 深拷贝(physical copy),三大件(bigthree problem)...
一般的我們喜歡這樣對對象賦值:
Person p1;Person p2=p1;
classT?object(another_object),?or????A?a(b);
classT?object?=?another?object;
class?A
{
//??…
};
int?main(?)
{
A?x;
A?y(x);
//?…
A?z?=?x;
? z?=?y;
}
這樣的話,如果成員變量中有指針的話,就容易造成指針的二次刪除。這樣就需要我們顯示的在類中實現
1、拷貝構造,
2、賦值運算符重載。
? ? ?1)、判斷是不是自賦值,2)、釋放舊空間,3)、開辟新空間。4)、內容本身的 ? ? ? ?拷貝,5)、返回*this
3、析構函數(釋放指針指向的空間)。
這三步使類實現深拷貝,從而避免淺拷貝的二次刪除問題。俗稱三大件。
class?Vector
{
private:
???int?*rep;
???int?size;
???void?clone(const?Vector&?a);
???void?dispose(?);
public:
???Vector(int?s=0); ?????
???//?a?default?constructor?initializing?all?members?of?rep?to?0?if?s?is?not?0.
???Vector(?int*,?int?); ????
???//?a?constructor?creates?a?Vector?object?from?an?ordinary?array
???Vector(const?Vector&?v); //?a?copy?constructor
???~Vector(?)?{dispose(?);} //?a?destructor
???int?get_size(?)?const?{return?size;} //?an?accessor
???const?Vector&?operator=(const?Vector&?x);
???int&?operator[?](int?index)?{return?rep[index];}
???const?int&?operator[?](int?index)?const?{return?rep[index];}
};
//Vector?v;
//V?=?a;
//Vector?v(a);
void?Vector::clone(const?Vector&?a)
{
???this->size?=?a.size;??????rep?=?new?int[size];
???for?(int?count?=?0;?count?<?size;?++count)
???rep[count]?=?a[count];?//?(*this)[count]?=?a[count];
??????????????????????????//?rep[count]?=?a.rep[count];
}
void?Vector::dispose(?)
{?
delete?[?]?rep;?
rep?=?NULL;
}
Vector::Vector(int?s)?:?size(s)
{
???if?(size?<=?0)
???{?rep?=?NULL;?}
???else
???{
??????rep?=?new?int[size];
??????for?(int?count?=?0;?count?<?size;?++count)
??????{?rep[count]?=?0;?}?????}
}
Vector::Vector(int*?a,?int?s)?:?size(s),?rep(new?int[s])
{
???for?(int?count?=?0;?count?<?size;?++count)
???{?rep[count]?=?a[count];?}
}
Vector::Vector(const?Vector&?v)
{?clone(v);?}
//for?example:?Vector?a,?v;?a.=(v);
const?Vector&?Vector::operator=(const?Vector&?x)
{
???if?(?this?!=?&x?)??//Vector?v;?Vector*?p?=?&v;?v?=?*p;
???{
??????delete?[]rep;
??????this->size?=?x.size;
???rep?=?new?int[size];
??????for?(int?count?=?0;?count?<?size;?++count)
??????rep[count]?=?x[count];
???}
???return?*this;
}
//?overloading?operator?<<,?not?a?friend?function
ostream&?operator<<(ostream&?out,?const?Vector&?x)
{
???int?s?=?x.get_size(?);
???for?(int?i?=?0;?i?<?s;?++i)
???{
??????out?<<?x[i]<<endl;?//?out<<x.rep[i]<<endl;
???}
???out?<<?endl;
???return?out;
}
bool?operator==(const?Vector&?a,?const?Vector&?b)
{
???bool?yes?=?true;
???if?(a.get_size(?)?!=?b.get_size(?))
???{?yes?=?false;?}
???else
???{
??????int?s,?index?=?0;
??????s?=?a.get_size(?);
??????while?(index?<?s?&&?a[index]?==?b[index])
??????{?++index;?}
??????if?(index?<?s)
??????{?yes?=?false;?}
???}
???return?yes;
}
int?main()
{
Vecter?vec1;
cout<<vec1<<endl;
int?array[5]?=?{1,2,3,4,5};
Vector?vec2(?array,?5?);
cout<<vec2<<endl;
Vector?vec3(?vec2?);??
cout<<vec3<<end;
if(?vec3?==?vec2?)
{
Cout<<”The?vector3?is?equal?to?vector2”<<endl;
}
Vector?vec4;
vec4?=?vec3;
cout<<vec4<<end;
return?0;
}
| 1.?實現一個字符串類String,功能包括: 1、Big Three 2、下標操作符重載 3、輸入輸出操作符重載 4、==操作符重載 5、+操作符重載 |
#include <iostream> using namespace std; class String { public:String(char* c=""):len(strlen(c)){if(!c){str=new char[1];strcpy(str,"");}else{str=new char[strlen(c)+1];strcpy(str,c);}}String(const String& s){len=s.len;if(!s.str){str=new char[1];strcpy(str,"");}else{str=new char[len+1];strcpy(str,s.str);}}~String(){if(str){delete []str;str=NULL;}}const String& operator=(const String& s){if(this!=&s){len=s.len;delete str;if(!s.str){str=new char[1];strcpy(str,"");}else{str=new char[len+1];strcpy(str,s.str);}}return *this;}const char& operator[](int index)const{return str[index];}char& operator[](int index){return str[index];}bool operator==(const String& s){if(len!=s.len)return false;while (len--){if((*this)[len]!=s[len])return false;}return true;}const String operator+(const String& s){char* p=new char[len+s.len+1];strcpy(p,str);strcat(p,s.str);String newStr(p);return newStr;} friend ostream& operator<<(ostream& out,const String & s); friend istream& operator>>(istream& in, String & s); private:int len;char* str; }; ostream& operator<<(ostream& out,const String & s) {out<<s.str<<" "<<s.len<<endl;return out; } istream& operator>>(istream& in,String & s) {cout<<"請輸入小于100的字符串"<<endl;delete s.str;s.str=new char[100];in>>s.str;s.len=strlen(s.str);return in; } int main() {String s1,s2;cin>>s1;cin>>s2;cout<<(s1==s2)<<endl;cout<<"s1+s2"<<endl;cout<<(s1+s2)<<endl;s1=s2;cout<<s1<<" s2= "<<s2;cout<<(s1==s2)<<endl;return 0; }
.?寫一個學生類,從person類繼承,增加的屬性為成績f和評語label(字符串)。
person: name,age,print(),要求使用三大件,輸出重載,==重載,下標重載。
#include<iostream> #include<string.h> using namespace std; class Person { friend ostream& operator<<(ostream& out,Person& p); public:Person(int a ,char * c):age(a){if(!c){name=NULL;}else{name=new char[strlen(c)+1];strcpy(name,c);}}Person(Person& p){if(!p.name){name=NULL;}else{name=new char[strlen(p.name)+1];strcpy(name,p.name);}}~Person(){if(name!=NULL)delete []name;}const Person& operator=(Person& p){if(this!=&p){delete[]name;name=new char[strlen(p.name)+1];strcpy(name,p.name);}return *this;}void print(){cout<<*this;} protected:int age;char* name;}; ostream& operator<<(ostream& out,Person& p) {out<<"姓名:"<<p.name<<" 年齡:"<<p.age<<endl;return out; } class Student:public Person { friend ostream& operator<<(ostream& out,Student& s); public:Student(int a,char* n,float fl=0,char* c=""):Person(a,n),f(fl){if(!c){lable=NULL;}else{lable=new char[strlen(c)+1];strcpy(lable,c);}}Student(Student& s):Person(s){if(!s.lable){f=s.f;lable=NULL;lable=new char[strlen(s.lable)+1];strcpy(lable,s.lable);}}~Student(){if(lable!=NULL)delete[] lable;}const Student& operator=(Student& s){if(this!=&s){Person::operator=(s);if(!s.lable){f=s.f;lable=NULL;}else{f=s.f;delete[]lable;lable=new char[strlen(s.lable)+1];strcpy(lable,s.lable);}}}void print(){cout<<*this;} private:float f;char* lable; }; ostream& operator<<(ostream& out,Student& s) {out<<"姓名:"<<s.name<<" 年齡:"<<s.age<<endl;out<<"成績:"<<s.f<<" 評語:"<<s.lable<<endl;return out; } int main() {Person *p=new Person(18,"小方");p->print();Student* s=new Student(18,"小芳",99,"山上有個姑娘叫小芳");s->print();Person* p2=s;p2->print();((Student*)p2)->print();(*((Student*)p2)).print();Student s1(99,"阿黃",99,"上有個姑娘叫阿黃");Person& p3=s1;p3.print();s1.print();((Student&)p3).print();return 0; }
1. Person為基類:虛函數為 dailywork() ~Person()
定義三個子類:Student Doctor(char* label) Driver(char* label)
主函數:定義基類指針數組,動態創建子類對象,調用成員函數,刪除創建的對象
#include<iostream.h>
#include<string.h>
class Person
{
friend ostream& operator<<(ostream& out,Person& p);
public:
?? ?Person(int a =0,char * c=""):age(a)
?? ?{
?? ??? ?if(!c)
?? ??? ?{
?? ??? ??? ?name=NULL;
?? ??? ?}
?? ??? ?else
?? ??? ?{
?? ??? ??? ?name=new char[strlen(c)+1];
?? ??? ??? ?strcpy(name,c);
?? ??? ?}
?? ?}
?? ?Person(const Person& p)
?? ?{
?? ??? ?if(!p.name)
?? ??? ?{
?? ??? ??? ?name=NULL;
?? ??? ?}
?? ??? ?else
?? ??? ?{
?? ??? ??? ?name=new char[strlen(p.name)+1];
?? ??? ??? ?strcpy(name,p.name);
?? ??? ?}
?? ?}
?? ?virtual~Person()
?? ?{
?? ??? ?if(name!=NULL)
?? ??? ??? ?delete []name;
?? ?}
?? ?virtual void? dailywork()
?? ?{
?? ??? ?cout<<"<^.^> 吃飯 勞動 睡覺 活下去 <^.^>";
?? ?}
?? ?const Person& operator=(const Person& p)
?? ?{
?? ??? ?if(this!=&p)
?? ??? ?{
?? ??? ??? ?delete[]name;
?? ??? ??? ?name=new char[strlen(p.name)+1];
?? ??? ??? ?strcpy(name,p.name);
?? ??? ?}
?? ??? ?return *this;
?? ?}
?? ?void print()
?? ?{
?? ??? ?cout<<*this;
?? ?}
protected:
?? ?int age;
?? ?char* name;
};
ostream& operator<<(ostream& out,Person& p)
{
?? ?out<<"姓名:"<<p.name<<"? 年齡:"<<p.age<<endl;
?? ?return out;
}
class Student:public Person
{
friend ostream& operator<<(ostream& out,Student& s);
public:
?? ?Student(int a,char* n,float fl=0,char* c=""):Person(a,n),f(fl)
?? ?{
?? ??? ?if(!c)
?? ??? ?{
?? ??? ??? ?lable=NULL;
?? ??? ?}
?? ??? ?else
?? ??? ?{
?? ??? ??? ?lable=new char[strlen(c)+1];
?? ??? ??? ?strcpy(lable,c);
?? ??? ?}
?? ?}
?? ?Student(Student& s):Person(s)
?? ?{
?? ??? ?if(!s.lable)
?? ??? ?{
?? ??? ??? ?f=s.f;
?? ??? ??? ?lable=NULL;
?? ??? ??? ?lable=new char[strlen(s.lable)+1];
?? ??? ??? ?strcpy(lable,s.lable);
?? ??? ?}
?? ?}
?? ?~Student()
?? ?{
?? ??? ?if(lable!=NULL)
?? ??? ??? ?delete[] lable;
?? ?}
?? ?void dailywork()
?? ?{
?? ??? ?Person::dailywork();
?? ??? ?cout<<"<^.^> 學習 學習 再學習 <^.^>"<<endl;
?? ?}
?? ?const Student& operator=(const Student& s)
?? ?{
?? ??? ?if(this!=&s)
?? ??? ?{
?? ??? ??? ?Person::operator=(s);
?? ??? ??? ?if(!s.lable)
?? ??? ??? ?{
?? ??? ??? ??? ?f=s.f;
?? ??? ??? ??? ?lable=NULL;
?? ??? ??? ?}
?? ??? ??? ?else
?? ??? ??? ?{
?? ??? ??? ??? ?f=s.f;
?? ??? ??? ??? ?delete[]lable;
?? ??? ??? ??? ?lable=new char[strlen(s.lable)+1];
?? ??? ??? ??? ?strcpy(lable,s.lable);
?? ??? ??? ?}
?? ??? ?}
?? ?}
?? ?void print()
?? ?{
?? ??? ?cout<<*this;
?? ?}
private:
?? ?float f;
?? ?char* lable;
};
ostream& operator<<(ostream& out,Student& s)
{
?? ?out<<"姓名:"<<s.name<<"? 年齡:"<<s.age<<endl;
?? ?out<<"成績:"<<s.f<<"? 評語:"<<s.lable<<endl;
?? ?return out;
}
class Doctor:public Person
{
public:
?? ?Doctor(int _age,char *_name,char* _lable):Person(_age,_name)
?? ?{
?? ??? ?if(!_lable)
?? ??? ?{
?? ??? ??? ?lable=new char[1];
?? ??? ??? ?strcpy(lable,"");
?? ??? ?}
?? ??? ?else
?? ??? ?{
?? ??? ??? ?lable=new char[strlen(_lable)+1];
?? ??? ??? ?strcpy(lable,_lable);
?? ??? ?}
?? ?}
?? ?Doctor(const Doctor& d):Person(d)
?? ?{
?? ??? ?if(!d.lable)
?? ??? ?{
?? ??? ??? ?lable=NULL;
?? ??? ?}
?? ??? ?else
?? ??? ?{
?? ??? ??? ?lable=new char[strlen(d.lable)+1];
?? ??? ??? ?strcpy(lable,d.lable);
?? ??? ?}
?? ?}
?? ?~Doctor()
?? ?{
?? ??? ?if(lable)
?? ??? ?{
?? ??? ??? ?delete []lable;
?? ??? ??? ?lable=NULL;
?? ??? ?}
?? ?}
?? ?const Doctor& operator=(const Doctor& d)
?? ?{
?? ??? ?if(this!=&d)
?? ??? ?{
?? ??? ??? ?Person::operator=(d);
?? ??? ??? ?if(!d.lable)
?? ??? ??? ?{
?? ??? ??? ??? ?lable=NULL;
?? ??? ??? ?}
?? ??? ??? ?else
?? ??? ??? ?{
?? ??? ??? ??? ?
?? ??? ??? ??? ?lable=new char[strlen(d.lable)+1];
?? ??? ??? ??? ?strcpy(lable,d.lable);
?? ??? ??? ?}
?? ??? ?}
?? ??? ?return *this;
?? ?}
?? ?void dailywork()
?? ?{
?? ??? ?Person::dailywork();
?? ??? ?cout<<"<^.^> 救死 扶傷 治病 抓藥 <^.^>"<<endl;
?? ?}
private:
?? ?char* lable;
friend? const ostream& operator<<(ostream& out,const Doctor & d);
};
const ostream& operator<<(ostream& out,const Doctor& d)
{
?? ?out<<(Person&)d<<endl;
?? ?out<<d.lable<<endl;
?? ?return out;
}
class Driver:public Person
{
public:
?? ?Driver(int _age,char *_name,char* _lable):Person(_age,_name)
?? ?{
?? ??? ?if(!_lable)
?? ??? ?{
?? ??? ??? ?lable=new char[1];
?? ??? ??? ?strcpy(lable,"");
?? ??? ?}
?? ??? ?else
?? ??? ?{
?? ??? ??? ?lable=new char[strlen(_lable)+1];
?? ??? ??? ?strcpy(lable,_lable);
?? ??? ?}
?? ?}
?? ?Driver(const Driver& d):Person(d)
?? ?{
?? ??? ?if(!d.lable)
?? ??? ?{
?? ??? ??? ?lable=NULL;
?? ??? ?}
?? ??? ?else
?? ??? ?{
?? ??? ??? ?lable=new char[strlen(d.lable)+1];
?? ??? ??? ?strcpy(lable,d.lable);
?? ??? ?}
?? ?}
?? ?~Driver()
?? ?{
?? ??? ?if(lable)
?? ??? ?{
?? ??? ??? ?delete []lable;
?? ??? ??? ?lable=NULL;
?? ??? ?}
?? ?}
?? ?const Driver& operator=(const Driver& d)
?? ?{
?? ??? ?if(this!=&d)
?? ??? ?{
?? ??? ??? ?Person::operator=(d);
?? ??? ??? ?if(!d.lable)
?? ??? ??? ?{
?? ??? ??? ??? ?lable=NULL;
?? ??? ??? ?}
?? ??? ??? ?else
?? ??? ??? ?{
?? ??? ??? ??? ?lable=new char[strlen(d.lable)+1];
?? ??? ??? ??? ?strcpy(lable,d.lable);
?? ??? ??? ?}
?? ??? ?}
?? ??? ?return *this;
?? ?}
?? ?void dailywork()
?? ?{
?? ??? ?Person::dailywork();
?? ??? ?cout<<"<^.^> 駕駛 開車 拉貨 跑四方? <^.^>"<<endl;
?? ?}
private:
?? ?char* lable;
friend const ostream& operator<<(ostream& out,const Driver & d);
};
const ostream& operator<<(ostream& out,const Driver & d)
{
?? ?out<<(Person&)d<<endl;
?? ?out<<d.lable<<endl;
?? ?return out;
}
int main()
{
?? ?Person *p=new Person(18,"小方");
?? ?p->print();
?? ?Student* s=new Student(18,"小芳",99,"山上有個姑娘叫小芳");
?? ?s->print();
?? ?Person* p2=s;
?? ?p2->print();
?? ?((Student*)p2)->print();
?? ?(*((Student*)p2)).print();
?? ?Student s1(99,"阿黃",99,"上有個姑娘叫阿黃");
?? ?Person& p3=s1;
?? ?p3.print();
?? ?s1.print();
?? ?((Student&)p3).print();
?? ?cout<<"====//開始====="<<endl;
?? ?Person array[3]={Person(30,"張二狗"),Person(18,"二鳳"),Person(18,"Mis Y")};
?? ?Person *parray[3];
?? ?parray[0]=array;
?? ?parray[1]=array+1;
?? ?parray[2]=array+2;
?? ?parray[0]->dailywork();
?? ?array[0].dailywork();
?? ?cout<<"========="<<endl;
?? ?parray[0]=new Student(20,"張三",99,"好學生");
?? ?parray[1]=new Driver(22,"李四","好司機");
?? ?parray[2]=new Doctor(30,"王五","好大夫");
?? ?for(int i=0;i<3;i++)
?? ?{
?? ??? ?parray[i]->dailywork();
?? ??? ?delete []parray[i];
?? ?}
?? ?//Student sarry();
?? ?//Student** sParry=new Student *[2];
?? ?//delete []sParry;
?? ?return 0;
}
轉載于:https://www.cnblogs.com/wsq724439564/p/3258151.html
總結
以上是生活随笔為你收集整理的[置顶] 运算符重载,浅拷贝(logical copy) ,vs, 深拷贝(physical copy),三大件(bigthree problem)...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 树:线索二叉树详解
- 下一篇: C语言(第二章):数据类型、运算符、表达