拷贝构造,操作符重载


  1. 拷贝构造

#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)

    {

       s= new char[1024];

       memset(s,0,1024);

       strcpy(s,it.s);

    }

 

    ~mystring()

    {

       cout << "~mystring" << endl;

    }

};

 

int main()

{

    mystring str1;

    strcpy(str1.s,"hello world");

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

    mystring str2 = str1;

 

//    mystring str2;

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

 

    cout << str2.s << endl;

    return 0;

}

执行后的效果是:

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

#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>

 

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;

    }

 

    mystring operator =(const mystring &it)//重载了一个=号操作符

    {

       cout << "= operator" << endl;

       memset(s, 0, 1024);

       strcpy(s, it.s);

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

       return *this;

    }

 

    mystring operator =(const char *str)//重载了一个=号操作符

    {

       memset(s, 0, 1024);

       strcpy(s, str);

       return *this;

    }

 

    mystring operator =(int i)//重载了一个=号操作符

    {

       memset(s, 0, 1024);

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

       return *this;

    }

 

    mystring operator + (const mystring &it)//重载了一个+号操作符

    {

       strcat(s, it.s);

       return *this;

    }

 

    mystring operator + (const char *str)//重载了一个+号操作符

    {

       strcat(s, str);

       return *this;

    }

 

    void operator +=(const char *str)//

    {

       strcat(this->s, str);

    }

 

    mystring operator + (int i)//重载了一个+号操作符,一元操作符重载

    {

       char temp[100] = {0};

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

       strcat(s, temp);

       return *this;

    }

    void operator <<(const char *str)//<<操作符定义为赋值

    {

       strcpy(s, str);

    }

 

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

    {

       strcpy(str, s);

    }

 

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

    {

       int len = strlen(s);

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

       {

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

       }

       return *this;

    }

 

    void * operator new(size_t size)//假设重载的new,那么必须重载delete

    {

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

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

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

       return p;

    }

 

    void * operator new[](size_t size)//假设重载的new,那么必须重载delete

    {

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

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

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

       return NULL;

    }

 

    void operator delete[](void *obj)

    {

       free((mystring *)obj);

       obj = NULL;

    }

 

    void operator delete(void *obj)

    {

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

       obj = NULL;//防止野指针

    }

 

    bool operator ==(const mystring &it)

    {

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

       {

           return true;

       }else

           return false;

    }

 

    bool operator ==(const char *str)

    {

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

       {

           return true;

       }else

           return false;

    }

 

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

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

    char &operator[](int index)

    {

       return s[index];

    }

 

    void operator ()(const char *str)//重载函数调用操作符

    {

       strcpy(s, str);

    }

 

    void operator ()(int i)

    {

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

    }

 

    operator int()

    {

       return atoi(s);

    }

 

    friend mystring operator +(const char *str, const mystring &it);

 

};

 

bool operator ==(const char *str, const mystring &it)

{

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

    {

       return true;

    }else

       return false;

}

 

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

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

 

mystring operator +(const char *str, const mystring &it)

{

    mystring str1;

    char buf[1024] = {0};

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

    strcpy(str1.s, buf);

    return str1;

}

 

mystring operator ++(mystring &it)

{

    int len = strlen(it.s);

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

    {

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

    }

    return it;

}

 

mystring operator +(int i, const mystring &it)

{

    mystring str1;

    char buf[1024] = {0};

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

    strcpy(str1.s, buf);

    return str1;

}

 

class demo

{

public:

    demo()

    {

 

    }

};

 

void test(int i)

{

    cout << i << endl;

}

 

 

int main()

{

//    mystring str;

//    str << "123";

 

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

 

    mystring *p = new mystring;

    delete p;

 

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

//    free(p);

 

 

    return 0;

}

 

 

int main04()

{

    mystring str1;

    str1 << "hello";

    mystring str2;

    str2 << "hello";

 

    if ("hello" == str1)

    {

       cout << "true" << endl;

    }else

    {

       cout << "fasle" << endl;

    }

 

    str1[2] = 'a';

 

    //str1("aaaaaaaa");

    str1(10);

 

    cout << str1.s << endl;

 

 

 

 

    return 0;

 

}

 

int main03()

{

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

    mystring str1;

    str1 =  "hello";

    mystring str2;

    str2 = " world";

    mystring str3;

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

    //str3 = str1 + "aaaaaaaaaaaa";

    //str3 = str1 + 100;

    //str3 = "AAAAA" + str1;

    str3 = 100 + str1;

    str3 += "BBBBBB";

    str3 << "CCCCC";

    char buf[1024] = {0};

    str3 >> buf;

    str2 = str3++;

    str2 = ++str3;

 

    mystring *pstr = new mystring;

    delete pstr;

 

    cout << str3.s << endl;

    return 0;

}

 

 

int main01()

{

    mystring str1;

    strcpy(str1.s, "hello world");

    mystring str2;

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

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

 

    cout << str2.s << endl;

 

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

 

    mystring str3;

 

    str3 = str2 = 100;

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

 

    cout << str2.s << endl;

 

    return 0;

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值