zoukankan      html  css  js  c++  java
  • 运算符重载

    new 、delete关键字的重载。

    重载new关键字的时候,返回值必须是void *

    并且:第一个形参必须是:size_t .

    new [] delete[] 关键字的重载,

    注:new 的重载与new [] 的重载 并不等价。delete 与delete[] 的重载并不等价。

    下图辅助理解,是之前某一次的运行结果。

    倒是没少删,多清空了一大块。

    总之 就是 多写几遍巩固一下,运算符的重载。然后 new delete new[] delete[] 的重载一边比较少见。这个需要对内存掌握的比较充分才好。

    然后对于++ 的重载。

    Object++; 的重载写法是: 类名 &operator++(){}

    ++Object; 的重载写法是: 类名 &operator++(int){}

    还有就是 如果没有区分前置后置,那么编译器就会都认为成是一个,但是并不知道别的编译器怎么处理,对于 vs来讲是这样的。

    对于 反制的写法,也就是 我们常见的 对于类似“+” 的重载都是对象在前

    写法为: 类名 &operator +(const char *s){}

    但是 +应该满足交换律 也就是 如果 const 写在前面对象写在后面也应该支持:

    其写法为:

    friend 类名 &operator+(const char *s,类名 对象){}//再加上前面的友元关键字。

    在写这个东西的时候,总觉得貌似可以把 friend去掉:

    发现还真不行,还是需要加上的。

    以下代码:

    #include <iostream>
    #include <string.h>
    #pragma warning(disable:4996)
    using namespace std;
    
    class MyString{
    public:
        char *str;
        MyString(){
            cout << "构造函数,地址:" <<&str<< endl;
            str = new char[256];
            memset(str, 0, 256);//内存置空。
        }
        MyString(const char *s){
            str = new char[256];
            strcpy(str, s);
        
        }
        MyString(const MyString &mystr){
            cout << "复制构造函数,地址:" << &str << endl;
            str = new char[256];
            //memset(str, 0, 256);
            strcpy(str, mystr.str);
        }
    
    
        ~MyString(){
            cout << "析构函数,地址:" << &str << endl;
            delete[]str;
        }
    
        /*注意他们的原型是:
        void operator =(const MyString &mystr){
            strcpy(str, mystr.str);
        }
        void operator = (const char *s){
            strcpy(str, s);
        }
        为了 满足 ms2 = ms1 = "lifei" 这样的语法结构,所以给了他们一个返回值。以 赋值表达式成立。这个回头可以看下人家是怎么写的。或者 现在看吧。
        */
        MyString &operator =(const MyString &mystr){//加上这句话,下面的 ms2 = ms1 就不再出错了。
            strcpy(str, mystr.str);
            return *this;
        }
        MyString &operator =(const char *s){
            strcpy(str, s);
            return *this;
        }
        MyString &operator = (const int i){//重载了int 的内容。
            sprintf(str, "%d", i);
            return *this;
        }
        /**
            应该是一个字符串拼接。
        */
        MyString &operator +(const char *s){
            sprintf(str, "%s%s", str, s);
            return *this;
        }
        MyString &operator +(const int i){
            sprintf(str, "%s%i", str, i);
            return *this;
        }
        //对象应该也可以+对象, 要在考虑到颠倒的情况,也就是 友元重载。还没试过,怎么分出去写,待会儿试验一个。现在吧。
        MyString &operator +(const MyString &mystr){
            sprintf(str, "%s%s", str, mystr.str);
            return *this;
        }
        friend MyString operator +(const char *s, const MyString &mystr){//这样就可以不写在外面了。
            //这里要重新建立一个对象。
            MyString myString;
            char buf[1024] = { 0 };
            sprintf(buf, "%s%s", s, mystr.str);
            myString = buf;
            return myString;
        }
        friend MyString operator +(const int i, const MyString &mystr){
            MyString myString;
            char buf[1024] = { 0 };
            sprintf(buf, "%d%s", i, mystr.str);
            myString = buf;
            return myString;
        }
    
        /* 这个也要重载int 和 char *的,到底要不要返回引用呢?,为了执行效率要不还是加上吧先。*/
        MyString &operator +=(const MyString &mystr){
            sprintf(str, "%s%s", str, mystr.str);
            return *this;
        }
        MyString &operator +=(const char *s){
            sprintf(str, "%s%s", str, s);
            return *this;
        }
        MyString &operator +=(const int i){
            sprintf(str, "%s%i", str, i);//其实开始这里我想到的是itoa。
            return *this;
        }
    
        //ms1 << "lifei"
        MyString &operator <<(const char *s){//定义为赋值操作。
            sprintf(str, "%s", s);
            return *this;
        }
        MyString &operator<<(const int i){
            sprintf(str, "%d", i);
            return *this;
        }
        MyString &operator<<(const MyString &mystr){
            sprintf(str, "%s", mystr.str);
            return *this;
        }
        
        //ms1++;
        MyString &operator++(){//我记得好像是 写上是一种操作方式,不写是另一种操作方式。 这样就重载了 前置 跟后置两种方式。这个是object++。
            int i = 0;
            for (i = 0; i < strlen(str); i++){
                str[i] = str[i]++;
            }        
            return *this;
        }
        //++ms1;不过好像并实现不了,先赋值,还是先运算那种关系的。
        MyString &operator++(int){//我记得好像是 写上是一种操作方式,不写是另一种操作方式。 这样就重载了 前置 跟后置两种方式。这个是 ++object。
            int i = 0;
            for (i = 0; i < strlen(str); i++){
                str[i] = str[i]--;
            }
            return *this;
        }
    
        //重载 new关键字
        void *operator new(size_t i){//重载new关键字的时候返回值的类型必须是void
            /*int *p;
            cout << sizeof(p) << endl;
            感觉貌似一个指针就是 4个字节。估计帮我屏蔽了底层了吧。
            */
            cout << i << endl;//这个的输出结果是4.所以就是一个指针的大小嘛!?~
    
            MyString *myptr = (MyString *)malloc(i);
    
            //return NULL;//返回空的时候没有调用构造函数,当返回myptr的时候 调用了构造函数。。。这个东西感觉很复杂。
            
            return myptr;
        }
        //重载delete的时候,返回值必须是void 并且 第一个参数 必须是 void* ,其实不记得也没有关系 ,只要使用某一个很智能的ide比如vs
        void operator delete(void *p){
            free((MyString *)p);//还记得我们的为什么要如此指定么,应该记得,根据类型决定到内存中,释放多大的内存空间。
            p = NULL;
        }
        // new 跟 new[] 是完全不同的,不要以为重载了new就是 重载了new[].这是两回事,要分开重载。
        void *operator new[](size_t size){
            cout << "重载了 new[]" << endl;
            cout << size << endl;//这个size的大小是  单个的 new 的 关键字里面的大小的数值乘以对象个数,最后+4.举例 本文中就是 4*2+4 = 12;
            MyString *myptr = (MyString *)malloc(size);
            memset(myptr, 0, size);
            cout << myptr << endl;
    
            return myptr;
        }
        void operator delete[](void *p){
                
            cout << "我的delete[]" << endl;
            free((MyString *)p);
            p = NULL;
    
        }
        char  &operator [](int index){
        
            return str[index];
        
        }
    
        
    
    
    
    
    };
    
    
    int main(){
    
        MyString ms1;
        //MyString ms2 = ms1;
        MyString ms2;
        MyString *ms5 = new MyString[2];
        cout << &ms5 << endl;
        cout << &ms5[0] << endl;
        cout << &ms5[1] << endl;
        ms5[0] = ms1;
        ms5[1] = ms2;
        ms5[0] = "lifei";
        cout << ms5[0][1] << endl;//重载一下。
        ms5[1] = 3+ms5[0];
        delete[]ms5;
    
        system("pause");
        return 0;
    
        MyString *ms3 = new MyString;
        cout << sizeof(ms3) << endl;
        delete ms3;
    
        //MyString ms4[] = {MyString("df"),MyString("sdf")};//算了并不知道 要怎么重载new[].感觉怎么也写不出来,那个使用语句。
        
        //ms1[2];//是不是可以重载一下[]。表示具体的某一个字符。
        int *p = new int[3];
    
        /*
        Part A.
        ms2 = ms1 = "lifei";
        ms1 = 3;
        cout << ms1.str << endl;
        ms2 = ms1 + "qingwa" + 3;
        cout << ms2.str << endl;
        MyString ms3 = ms1 + ms2;
        cout << ms3.str << endl;
        memset(ms1.str, 0, 256);
        memset(ms2.str, 0, 256);
        ms1 = " come on!";
        cout << ms1.str << endl;
        ms2 = "lifei" + ms1;
        cout << ms2.str << endl;
    
        ms1 = 3 + ms2;
        cout << ms1.str <<endl;*/
    
        /*
        Part B.
        MyString ms3;
        ms1 = "li";
        ms2 = "fei";
        ms2 = ms1++;
        cout << ms1.str << endl;
        cout << ms2.str << endl;
        ms2 = ++ms1;
        cout << ms1.str << endl;
        cout << ms2.str << endl;
    
        ms3 = ms1 += ms2;//这个语法就比较复杂了
        //我都不知道是不是我想要的结果了
        MyString ms4 = ms3 + 5;
        cout << ms4.str << endl;//还是。。。
        */
    
        //用. 的话要这样写: strcpy(ms2.str,"lifei"); 要么别用。仔细想想 ms2.str 是个地址啊!地址怎么能给一个 
        //ms2.str = "asdf";倒是也让赋值了,不过结果就是不对。
    
    
        
    
    
    
    
    
    
    
    
        system("pause");
        return 0;
    
    }
  • 相关阅读:
    程序跳转到itunes商店
    程序跳转到itunes商店
    app被Rejected 的各种原因翻译。这个绝对有用
    app被Rejected 的各种原因翻译。这个绝对有用
    iphone开发中使用nib(xib)文件的内存管理
    iphone开发中使用nib(xib)文件的内存管理
    Resource Management in View Controllers
    Linux_RHEL7_YUM
    Python基本语法_函数_返回值
    Python基本语法_函数_返回值
  • 原文地址:https://www.cnblogs.com/letben/p/5301939.html
Copyright © 2011-2022 走看看