zoukankan      html  css  js  c++  java
  • [置顶] 运算符重载,浅拷贝(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;
    }


  • 相关阅读:
    react路由组件&&非路由组件
    react函数式组件(非路由组件)实现路由跳转
    react使用antd组件递归实现左侧菜单导航树
    【LeetCode】65. Valid Number
    【LeetCode】66. Plus One (2 solutions)
    【LeetCode】68. Text Justification
    【LeetCode】69. Sqrt(x) (2 solutions)
    【LeetCode】72. Edit Distance
    【LeetCode】73. Set Matrix Zeroes (2 solutions)
    【LeetCode】76. Minimum Window Substring
  • 原文地址:https://www.cnblogs.com/wsq724439564/p/3258151.html
Copyright © 2011-2022 走看看