[置顶] 运算符重载,浅拷贝(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;
}
[置顶] 运算符重载,浅拷贝(logical copy) ,vs, 深拷贝(physical copy),三大件(bigthree problem)的更多相关文章
- [置顶] operator overloading(操作符重载,运算符重载)运算符重载,浅拷贝(logical copy) ,vs, 深拷贝(physical copy)
operator overloading(操作符重载,运算符重载) 所谓重载就是重新赋予新的意义,之前我们已经学过函数重载,函数重载的要求是函数名相同,函数的参数列表不同(个数或者参数类型).操作符重 ...
- 运算符重载,浅拷贝(logical copy) ,vs, 深拷贝(physical copy),三大件(bigthree problem)
一般的我们喜欢这样对对象赋值: Person p1;Person p2=p1; classT object(another_object), or A a(b); classT object = ...
- 浅拷贝(Shallow Copy) VS 深拷贝(Deep Copy)
首先,深拷贝和浅拷贝针对的是对象类型(对象,数组,函数) 浅拷贝指的是只是拷贝了对象的引用地址,彼此之间高耦合,一个改变,另一个可能也随之改变: 深拷贝是指只是完整的将变量的值拷贝过来,是一个新的对象 ...
- 由Python的浅拷贝(shallow copy)和深拷贝(deep copy)引发的思考
首先查看拷贝模块(copy)发现: >>> help(copy)Help on module copy:NAME copy - Generic (shallow and dee ...
- [置顶] think in java interview-高级开发人员面试宝典(三)
收集自Oracle公司的10次(60道)电话面试全部问答(英语) Q: What environment variables do I need to set on my machine in ord ...
- C++学习6-面向对象编程基础(运算符重载、类的派生与继承、命名空间)
运算符重载 重载的运算符是具有特殊名字的函数:它们的名字由关键字operator和其后要定义的运算符号共同组成.重载的运算符是遵循函数重载的选择原则,根据不同类型或不同参数来选择不同的重载运算符. 运 ...
- jQuery操作table数据上移、下移和置顶
jQuery 操作table中的tr换行的步骤如下: 1.获取当前tr var $tr = $(this).parents("tr"); 2.移动tr //上移 $tr.prev( ...
- [置顶] C++基础之六:运算符的重载
网上太多有关运算符的重载了,但是写的太过的详细,不适合新手入门,特别是那什么++和--的前增量后增量重载,一元二元运算符重载,特殊运算符,下标运算符,new和delete,甚至是指针运算符的重载,吓退 ...
- C/C++对Lu系统内置动态对象进行运算符重载
欢迎访问Lu程序设计 C/C++对Lu系统内置动态对象进行运算符重载 1 说明 要演示本文的例子,你必须下载Lu32脚本系统.本文的例子需要lu32.dll.lu32.lib.C格式的头文件lu32. ...
随机推荐
- CodeForce---Educational Codeforces Round 3 USB Flash Drives (水题)解题报告
对于这题明显是用贪心算法来解决问题: 下面贴出笔者的代码: #include<cstdio> #include<iostream> #include<algorithm& ...
- USB HID报告及报告描述符简介
在USB中,USB HOST是通过各种描述符来识别设备的,有设备描述符,配置描述符,接口描述符,端点描述符,字符串描述符,报告描述符等等.USB报告描述符(Report Descriptor)是HID ...
- 【HTML】Advanced7:HTML5 Forms Pt. 2: Attributes and Data Lists
1.<label for"" ></label> <input type="email" placeholder=" & ...
- sqlite 修改表名,合并数据库(文件)
修改表名:ALTER TABLE orig_table_name RENAME TO tmp_table_name; 将某个数据库的一个表的数据插入到另一个数据库的某个表里:1.先连接数据库A2.再a ...
- ffmpeg编码YUV420视频序列
依旧是这里的测试序列 http://www.cnblogs.com/zzugyl/p/3678865.html测试了JM和libx264的编解码质量后来用ffmpeg转码 发现忘记了命令行转码的命令网 ...
- linux大于2T的磁盘使用GPT分区方式
MBR(Master Boot Record)(主引导记录)和GPT(GUID Partition Table)(GUID意为全局唯一标识符)是在磁盘上存储分区信息的两种不同方式 对于传统的MBR分区 ...
- jquery foreach
<form id="input_iForm" action="${pageContext.request.contextPath}/transfer/input_s ...
- 用Modelsim仿真QuartusII综合后网表时库的添加方法(转)
这两天做综合后仿真,发现FPGA器件库又不会加了,无奈上网找方法.说起来不好意思,很早就接触Modelsim这个仿真软件了,可是没有好好琢磨.把这两天找的方法贴出来,再加上自己的理解,以后忘了可以上博 ...
- 修改HTMLTestRunner模板
---恢复内容开始--- 1.修改bug(passCase不标色和加粗) style = (n == 2 and 'errorCase') or (n == 1 and 'failCase') or ...
- POJ 3130 How I Mathematician Wonder What You Are! /POJ 3335 Rotating Scoreboard 初涉半平面交
题意:逆时针给出N个点,求这个多边形是否有核. 思路:半平面交求多边形是否有核.模板题. 定义: 多边形核:多边形的核可以只是一个点,一条直线,但大多数情况下是一个区域(如果是一个区域则必为 ).核内 ...