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


  • 相关阅读:
    C# MenuStrip Visible=false bug的解决方案
    WTL 命令行编译
    LCS 最长公共字串算法实现
    调用系统打开文件OpenAs_RunDLL
    ToolStripSplitButton Checked 效果
    WTL 中使用GDI+ 备忘
    P7482 不条理狂诗曲 题解
    CF1557 比赛记录
    P2519 [HAOI2011]problem a 题解
    CF1540B Tree Array 题解
  • 原文地址:https://www.cnblogs.com/wsq724439564/p/3258151.html
Copyright © 2020-2023  润新知