• c++知识点总结--友元&运算符重载


    友元函数(不属于类)
    可以访问类的私有变量,以及私有函数
    友元函数在类内声明需要friend关键字,类外定义就不需要
    友元函数可以直接在类内定义
    友元函数必须包含对象指针
     
    友元类(不适用继承,只适用当前类)
    若F类是A类的友元类,则F类的所有成员函数都是A类的友元函数
    友元类通常设计为一种对数据操作或类之间传递消息的辅助类
     
    (1) 友元关系不能被继承。
    (2) 友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。
    (3) 友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的申明
     
    运算符重载
      1、重载的操作符(部分例外)不必是成员函数,但重载的操作符至少得有一个是用户自定义的类,这是为了防止用户为标准类型重载操作符,例如将两个整数的加法重载为乘法之类的;
      2、使用重载操作符不能违反原来的语法,例如不能把二元操作符重载为一元操作符。同样不能改变其优先级。
      3、不能定义新的操作符。
      4、并非所有的操作符都能被重载
        5、大多数操作符都能通过成员或非成员函数重载,但以下的操作符只能通过成员函数重载:
     假若我们重载了加法操作符,使得其 A + 3能正常使用,那么如果是3 + A 呢?因为重载时规定加号左边是对象右边是int,所以3 + A是非法的。如何解决呢?一般是使用友元。
    #include <iostream>
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.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=mystring
        mystring &operator =(const mystring &it)//重载了一个=号操作符
        {
            cout << "= operator" << endl;
            memset(s, 0, 1024);
            strcpy(s, it.s);
            return *this;
        }
        //mystring=char*
        mystring &operator =(const char *str)//重载了一个=号操作符
        {
            cout << "char = operator" << endl;
            memset(s, 0, 1024);
            strcpy(s, str);
            return *this;
        }
        //mystring=int
        mystring &operator =(int i)//重载了一个=号操作符
        {
            memset(s, 0, 1024);
            sprintf(s, "%d", i);
            return *this;
        }
        //mystring+mystring
        mystring &operator + (const mystring &it)//重载了一个+号操作符
        {
            strcat(s, it.s);
            return *this;
        }
        //mystring+char*
        mystring &operator + (const char *str)//重载了一个+号操作符
        {
            strcat(s, str);
            return *this;
        }
    
        void operator +=(const char *str)//
        {
            strcat(this->s, str);
        }
        //mystring+int
        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->s和it的s相同,就返回true
            {
                return true;
            }else
                return false;
        }
    
        bool operator ==(const char *str)
        {
            if (strcmp(s, str) == 0)//如果this->s和it的s相同,就返回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;
    }
    //char*+mystring
    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;
    }
    int main(int argc, char *argv[])
    {
       /* mystring str1;
        strcpy(str1.s, "hello world");
        mystring str2;
        str2 = str1;//这个过程不是拷贝构造的过程,只是=号操作
        cout<<str2.s<<endl;
        //str2.operator =(str1);//和直接写=号是一摸一样的
    
        str2 = "test";//C++编译器不能理解把一个字符串赋给一个类是什么含义
        cout<<str2.s<<endl;
    
        mystring str3;
        str3 = str2 = 100;
        //str3 = str2.operator =(100);//上一条语句的等效语法
        */
    
        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;
    }
  • 相关阅读:
    Linux下vi命令大全
    Ubuntu的cron日志在哪里?
    如何使用DNN中的Calendar控件
    对DNN的理解:
    “SQL Server does not allow remote connections”错误的解决
    如何去除Search Skin ojbect中的"web"和"site"选项按键
    DNN发邮件通知4.8.2有漏洞,最好升级到新版本
    模块开发中一点疑惑?
    经典ASP代码大集合
    漂亮button
  • 原文地址:https://www.cnblogs.com/tla001/p/6680671.html
Copyright © 2020-2023  润新知