• 拷贝构造,操作符重载


    
    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;

    }

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    设计模式之工厂模式 练习
    c++智能指针(1)
    记录下 UTF6 GBK 转换函数
    ip白名单 通过* ? 检测IP匹配 轻量级
    stl学习记录(2)
    boost 学习(1)
    stl string 小练习
    stl string 使用指定的分隔符分割成数个子字符串
    [open source] skinbuilder发布
    Builder模式实例分析(C语言版)
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/3984674.html
Copyright © 2020-2023  润新知