首页 > 代码库 > 拷贝构造,操作符重载

拷贝构造,操作符重载


  1. 拷贝构造

#include<iostream>

#include<string.h>

 

usingnamespacestd;

 

classmystring

{

public:

   char*s;

public:

   mystring()

   {

       s=newchar[1024];

       cout<< "mystring"<< endl;

   }

   //拷贝构造

   mystring(constmystring&it)

   {

       s=newchar[1024];

       memset(s,0,1024);

       strcpy(s,it.s);

   }

 

   ~mystring()

   {

       cout<< "~mystring"<< endl;

   }

};

 

intmain()

{

   mystringstr1;

   strcpy(str1.s,"helloworld");

   //这样的方式仅仅调用了一次构造方法

   mystringstr2=str1;

 

//   mystringstr2;

//   str2=str1; //这个过程不是拷贝构造的过程,仅仅是=号操作

 

   cout<< str2.s<< endl;

   return0;

}

执行后的效果是:

当把代码改成以下的方式的时候,运行结果例如以下:

#include <iostream>
#include <string.h>
 
using namespace std;
 
class mystring
{
public:
    char *s;
public:
    mystring()
    {
        s = new char[1024];
        cout << "mystring" << endl;
    }
    //拷贝构造
    mystring(const mystring &it)
{
    cout << "copy mystring" << endl;
        s= new char[1024];
        memset(s,0,1024);
        strcpy(s,it.s);
    }
 
    ~mystring()
    {
        cout << "~mystring" << endl;
        delete []s;
}
};
 
int main()
{
    mystring str1;
    strcpy(str1.s,"hello world");
    //这样的方式仅仅调用了一次构造方法
    //mystring str2 = str1;
 
    mystring str2;
    str2 = str1;  //这个过程不是拷贝构造的过程,仅仅是=号操作
 
    cout << str2.s << endl;
    return 0;
}
str1 = str2的本质

2.操作符重载规则

重载操作符函数能够对操作作出新的解释,但原有基本予以不变:

A:不改变操作符的优先级

B:不改变操作符的结合性

C:不改变操作符须要的操作数

D:不能创建新的操作符

成员的语法形式为:

        类型类名::operator op(參数表)

{

   //相对于该类定义的操作

}

 重载赋值操作符

 赋值操作符重载用于对象数据的复制

 operator= 必须重载为成员函数

 voidoperator = (const classname &it);

 classname &operator = (const classname &it);

 返回引用会支持例如以下语法:obj1= obj2 = obj3;

 

3.操作符重载的案例:

#include<iostream>

#include<stdlib.h>

#include<string.h>

 

usingnamespacestd;

 

classmystring

{

public:

   char*s;

public:

   mystring()

   {

       s=newchar[1024];

       cout<< "mystring"<< endl;

   }

   mystring(constmystring&it)//深拷贝

   {

       cout<< "copymystring" << endl;

       s=newchar[1024];

       memset(s,0,1024);

       strcpy(s,it.s);

   }

 

   ~mystring()

   {

       cout<< "~mystring"<< endl;

       delete[]s;

   }

 

   mystringoperator=(constmystring&it)//重载了一个=号操作符

   {

       cout<< "=operator" << endl;

       memset(s,0,1024);

       strcpy(s,it.s);

       //在这个过程中调用了深拷贝的过,这里是以个暂时的拷贝过程,拷贝完毕之后调用深拷贝

       return*this;

   }

 

   mystringoperator=(constchar*str)//重载了一个=号操作符

   {

       memset(s,0,1024);

       strcpy(s,str);

       return*this;

   }

 

   mystringoperator=(inti)//重载了一个=号操作符

   {

       memset(s,0,1024);

       sprintf(s,"%d",i);

       return*this;

   }

 

   mystringoperator+(constmystring&it)//重载了一个+号操作符

   {

       strcat(s,it.s);

       return*this;

   }

 

   mystringoperator+(constchar*str)//重载了一个+号操作符

   {

       strcat(s,str);

       return*this;

   }

 

   voidoperator+=(constchar*str)//

   {

       strcat(this->s,str);

   }

 

   mystringoperator+(inti)//重载了一个+号操作符,一元操作符重载

   {

       chartemp[100]={0};

       sprintf(temp,"%d",i);

       strcat(s,temp);

       return*this;

   }

   voidoperator<<(constchar*str)//<<操作符定义为赋值

   {

       strcpy(s,str);

   }

 

   voidoperator>>(char*str)//<<操作符定义为赋值

   {

       strcpy(str,s);

   }

 

   mystringoperator++(int)//重载++操作符的函数int參数是固定

   {

       intlen=strlen(s);

       for(inti=0;i<len;i++)

       {

           s[i]++;//s的第一个成员char+1,就是将s[0]相应字符的ASCII+1

       }

       return*this;

   }

 

   void*operatornew(size_tsize)//假设重载的new,那么必须重载delete

   {

       //參数size就是sizeof(mystring)的大小.

       cout<< "size= "<< size<< endl;

       mystring*p=(mystring*)malloc(size);

       returnp;

   }

 

   void*operatornew[](size_tsize)//假设重载的new,那么必须重载delete

   {

       //參数size就是sizeof(mystring)的大小*new[x]+4个字节.

       cout<< "size= "<< size<< endl;

       //mystring*p=(mystring*)malloc(size);

       returnNULL;

   }

 

   voidoperatordelete[](void*obj)

   {

       free((mystring*)obj);

       obj=NULL;

   }

 

   voidoperatordelete(void*obj)

   {

       free((mystring*)obj);//不能直接free一个void*

       obj=NULL;//防止野指针

   }

 

   booloperator==(constmystring&it)

   {

       if(strcmp(s,it.s)==0)//假设this->sits同样,就返回true

       {

           returntrue;

       }else

           returnfalse;

   }

 

   booloperator==(constchar*str)

   {

       if(strcmp(s,str)==0)//假设this->sits同样,就返回true

       {

           returntrue;

       }else

           returnfalse;

   }

 

   //假设返回的是char,代表的是一个右值,右值是不能直接赋值的,

   //假设返回的是char的引用,那么[]就能够当左值使用了

   char&operator[](intindex)

   {

       returns[index];

   }

 

   voidoperator()(constchar*str)//重载函数调用操作符

   {

       strcpy(s,str);

   }

 

   voidoperator()(inti)

   {

       sprintf(s,"%d",i);

   }

 

   operatorint()

   {

       returnatoi(s);

   }

 

   friendmystringoperator+(constchar*str,const mystring&it);

 

};

 

booloperator==(constchar*str,constmystring&it)

{

   if(strcmp(str,it.s)==0)

   {

       returntrue;

   }else

       returnfalse;

}

 

//操作符重载,有一个最基本条件,就是一定有一个一元是一个自己定义的C++

//假设两个都是基本数据类型操作符重载是非法的

 

mystringoperator+(constchar*str,constmystring&it)

{

   mystringstr1;

   charbuf[1024]={0};

   sprintf(buf,"%s%s",str,it.s);

   strcpy(str1.s,buf);

   returnstr1;

}

 

mystringoperator++(mystring&it)

{

   intlen=strlen(it.s);

   for(inti=0;i<len;i++)

   {

       it.s[i]++;//s的第一个成员char+1,就是将s[0]相应字符的ASCII+1

   }

   returnit;

}

 

mystringoperator+(inti,constmystring&it)

{

   mystringstr1;

   charbuf[1024]={0};

   sprintf(buf,"%d%s",i,it.s);

   strcpy(str1.s,buf);

   returnstr1;

}

 

classdemo

{

public:

   demo()

   {

 

   }

};

 

voidtest(inti)

{

   cout<< i<< endl;

}

 

 

intmain()

{

//   mystringstr;

//   str<<"123";

 

//   test(str);//导致C++编译器自己主动的配备int()操作符

 

   mystring*p=newmystring;

   deletep;

 

//   mystring*p=(mystring*)malloc(sizeof(mystring));

//   free(p);

 

 

   return0;

}

 

 

intmain04()

{

   mystringstr1;

   str1<<"hello";

   mystringstr2;

   str2<<"hello";

 

   if("hello"==str1)

   {

       cout<< "true"<< endl;

   }else

   {

       cout<< "fasle"<< endl;

   }

 

   str1[2]=‘a‘;

 

   //str1("aaaaaaaa");

   str1(10);

 

   cout<< str1.s<< endl;

 

 

 

 

   return0;

 

}

 

intmain03()

{

   cout<< "mystringsize ="<< sizeof(mystring)<< endl;

   mystringstr1;

   str1= "hello";

   mystringstr2;

   str2="world";

   mystringstr3;

   //str3=str1+str2;//C++编译器来讲,不能识别两个类+是什么含义

   //str3=str1+"aaaaaaaaaaaa";

   //str3=str1+100;

   //str3="AAAAA"+str1;

   str3=100+str1;

   str3+="BBBBBB";

   str3<<"CCCCC";

   charbuf[1024]={0};

   str3>>buf;

   str2=str3++;

   str2=++str3;

 

   mystring*pstr=newmystring;

   deletepstr;

 

   cout<< str3.s<< endl;

   return0;

}

 

 

intmain01()

{

   mystringstr1;

   strcpy(str1.s,"helloworld");

   mystringstr2;

   str2=str1;//这个过程不是拷贝构造的过程,仅仅是=号操作

   //str2.operator=(str1);//和直接写=号是一摸一样的

 

   cout<< str2.s<< endl;

 

   str2="test";//C++编译器不能理解把一个字符串赋给一个类是什么含义

 

   mystringstr3;

 

   str3=str2=100;

   //str3=str2.operator=(100);//上一条语句的等效语法

 

   cout<< str2.s<< endl;

 

   return0;

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

拷贝构造,操作符重载