[置顶] 运算符重载,浅拷贝(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;
}


posted @ 2013-08-05 20:20  shouqiang Wei  阅读(340)  评论(0编辑  收藏  举报