zoukankan      html  css  js  c++  java
  • 类型转换运算符、*运算符重载、->运算符重载、operator new 和 operator delete

    一、类型转换运算符

    必须是成员函数,不能是友元函数
    没有参数
    不能指定返回类型
    函数原型:operator 类型名();

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    #ifndef _INTEGER_H_
    #define _INTEGER_H_

    class Integer
    {
    public:
        Integer(int n);
        ~Integer();

        Integer &operator++();
        //friend Integer& operator++(Integer& i);

        Integer operator++(int n);
        //friend Integer operator++(Integer& i, int n);

        operator int();

        void Display() const;
    private:
        int n_;
    };

    #endif // _INTEGER_H_
     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
     
    #include "Integer.h"
    #include <iostream>
    using namespace std;

    Integer::Integer(int n) : n_(n)
    {
    }

    Integer::~Integer()
    {
    }

    Integer &Integer::operator ++()
    {
        //cout<<"Integer& Integer::operator ++()"<<endl;
        ++n_;
        return *this;
    }

    //Integer& operator++(Integer& i)
    //{
    //  //cout<<"Integer& operator++(Integer& i)"<<endl;
    //  ++i.n_;
    //  return i;
    //}

    Integer Integer::operator++(int n)
    {
        //cout<<"Integer& Integer::operator ++()"<<endl;
        //n_++;
        Integer tmp(n_);
        n_++;
        return tmp;
    }

    //Integer operator++(Integer& i, int n)
    //{
    //  Integer tmp(i.n_);
    //  i.n_++;
    //  return tmp;
    //}

    Integer::operator int()
    {
        return n_;
    }

    void Integer::Display() const
    {
        cout << n_ << endl;
    }
     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    #include "Integer.h"
    #include <iostream>
    using namespace std;

    int add(int a, int b)
    {
        return a + b;
    }

    int main(void)
    {
        Integer n(100);
        n = 200;
        n.Display();

        int sum = add(n, 100);

        cout << sum << endl;

        int x = n;
        int y = static_cast<int>(n);

        return 0;
    }

    其中n = 200; 是隐式将int 转换成Interger类;int x = n; 是调用operator int 将Interger 类转换成int,也可以使用static_cast 办到;此外add 函数传参时也会调用operator int 进行转换。


    二、->运算符重载

    类* operator->();

    类& operator*();

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
     
    #include <iostream>
    using namespace std;

    class DBHelper
    {
    public:
        DBHelper()
        {
            cout << "DB ..." << endl;
        }
        ~DBHelper()
        {
            cout << "~DB ..." << endl;
        }

        void Open()
        {
            cout << "Open ..." << endl;
        }

        void Close()
        {
            cout << "Close ..." << endl;
        }

        void Query()
        {
            cout << "Query ..." << endl;
        }
    };

    class DB
    {
    public:
        DB()
        {
            db_ = new DBHelper;
        }

        ~DB()
        {
            delete db_;
        }

        DBHelper *operator->()
        {
            return db_;
        }

        DBHelper &operator*()
        {
            return *db_;
        }
    private:
        DBHelper *db_;
    };


    int main(void)
    {
        DB db;
        db->Open();
        db->Query();
        db->Close();

        (*db).Open();
        (*db).Query();
        (*db).Close();

        return 0;
    }

    db->Open(); 等价于 (db.operator->())->Open(); 会调用operator-> 返回DBHelper类的指针,调用DBHelper的成员函数Open()。这样使用的好处是不需要知道db 对象什么时候需要释放,当生存期结束时,会调用DB类的析构函数,里面delete db_; 故也会调用DBHelper类的析构函数。

    (*db).Open(); 等价于(db.operator*()).Open();


    三、operator new 和 operator delete

    前面曾经提过:实际上new 有三种用法,包括operator new、new operator、placement new,new operator 包含operator new,而placement new 则没有内存分配而是直接调用构造函数。下面看例子:

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
     
    #include <iostream>
    using namespace std;

    class Test
    {
    public:
        Test(int n) : n_(n)
        {
            cout << "Test(int n) : n_(n)" << endl;
        }
        Test(const Test &other)
        {
            cout << "Test(const Test& other)" << endl;
        }
        ~Test()
        {
            cout << "~Test()" << endl;
        }
        /****************************************************************/
        void *operator new(size_t size)
        {
            cout << "void* operator new(size_t size)" << endl;
            void *p = malloc(size);
            return p;
        }

        void operator delete(void *p) //与下面的operator delete函数类似,共存的话优先;
        {
            //匹配上面的operator new 函数
            cout << "void operator delete(void* p)" << endl;
            free(p);
        }

        void operator delete(void *p, size_t size)
        {
            cout << "void operator delete(void* p, size_t size)" << endl;
            free(p);
        }
        /**********************************************************************/

        void *operator new(size_t size, const char *file, long line)
        {
            cout << "   void* operator new(size_t size, const char* file, long line);" << endl;
            cout << file << ":" << line << endl;
            void *p = malloc(size);
            return p;
        }

        void operator delete(void *p, const char *file, long line)
        {
            cout << "   void operator delete(void* p, const char* file, long line);" << endl;
            cout << file << ":" << line << endl;
            free(p);
        }

        void operator delete(void *p, size_t size, const char *file, long line)
        {
            cout << "void operator delete(void* p, size_t size, const char* file, long line);" << endl;
            cout << file << ":" << line << endl;
            free(p);
        }
        /**************************************************************************/
        void *operator new(size_t size, void *p)
        {
            cout << "void* operator new(size_t size, void* p);" << endl;
            return p;
        }

        void operator delete(void *, void *)
        {
            cout << "void operator delete(void *, void *);" << endl;
        }
        /**************************************************************************/
        int n_;
    };

    /*************** global **********************************************/

    void *operator new(size_t size)
    {
        cout << "global void* operator new(size_t size)" << endl;
        void *p = malloc(size);
        return p;
    }

    void operator delete(void *p)
    {
        cout << "global void operator delete(void* p)" << endl;
        free(p);
    }
    /**********************************************************************/

    void *operator new[](size_t size)
    {
        cout << "global void* operator new[](size_t size)" << endl;
        void *p = malloc(size);
        return p;
    }

    void operator delete[](void *p)
    {
        cout << "global void operator delete[](void* p)" << endl;
        free(p);
    }
    /***********************************************************************/

    int main(void)
    {
        Test *p1 = new Test(100);   // new operator = operator new + 构造函数的调用
        delete p1;

        char *str1 = new char;
        delete str1;

        char *str2 = new char[100];
        delete[] str2;

        char chunk[10];


        Test *p2 = new (chunk) Test(200);   //operator new(size_t, void *_Where)
        // placement new,不分配内存 + 构造函数的调用
        cout << p2->n_ << endl;
        p2->~Test();                        // 显式调用析构函数

        //Test* p3 = (Test*)chunk;
        Test *p3 = reinterpret_cast<Test *>(chunk);
        cout << p3->n_ << endl;



    #define new new(__FILE__, __LINE__)
        //Test* p4 = new(__FILE__, __LINE__) Test(300);
        Test *p4 = new Test(300);
        delete p4;

        return 0;
    }


    从输出可以看出几点:

    1、new operator 是分配内存(调用operator new) + 调用构造函数

    2、operator new 是只分配内存,不调用构造函数

    3、placement new 是不分配内存(调用operator new(与2是不同的函数) 返回已分配的内存地址),调用构造函数

    4、delete 是先调用析构函数,再调用operator delete.

    5、如果new 的是数组,对应地也需要delete [] 释放

    注意:

    1、如果存在继承或者对象成员,那么调用构造函数或者析构函数时将有多个,按一定顺序调用,参见这里

    2、假设存在继承,delete 基类指针;涉及到虚析构函数的问题,参见这里

    最后还存在一点疑问的是 delete p4 为什么调用的不是 void operator delete(void* p, const char* file, long line); 而是

    void operator delete(void* p) ; 希望有明白的朋友告诉我一声。


    参考:

    C++ primer 第四版
    Effective C++ 3rd
    C++编程规范

  • 相关阅读:
    DBA_Oracle Erp重启Database/Application/Concurrent/Apache(案例)
    DBA_Oracle Erp R12安装虚拟机镜像IP修正(案例)
    RMAN_学习实验2_RMAN Duplicate复制数据库过程(案例)
    RMAN_学习实验1_RMAN备份标准过程(案例)
    PLSQL_基础系列12_替换函数用法REPLACE / TRANSLATE / REGEXP_REPLACE
    PLSQL_基础系列11_递归和层次查询CONNECT BY(案例)
    DBA_Oracle Sort排序处理空间耗用(概念)
    DBA_Oracle性能优化的基本方法概述(方法论)
    DBA_Oracle海量数据处理分析(方法论)
    PLSQL_基础系列10_子查询WITH AS(案例)
  • 原文地址:https://www.cnblogs.com/alantu2018/p/8471064.html
Copyright © 2011-2022 走看看