类型转换运算符、*运算符重载、->运算符重载、operator new 和 operator delete
一、类型转换运算符
必须是成员函数,不能是友元函数
没有参数
不能指定返回类型
函数原型:operator 类型名();
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 Integer &operator++(); Integer operator++(int n); operator int(); void Display() const; #endif // _INTEGER_H_ |
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 ++() //Integer& operator++(Integer& i) Integer Integer::operator++(int n) //Integer operator++(Integer& i, int n) Integer::operator int() void Integer::Display() const |
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) int main(void) int sum = add(n, 100); cout << sum << endl; int x = n; return 0; |
其中n = 200; 是隐式将int 转换成Interger类;int x =
n; 是调用operator int 将Interger 类转换成int,也可以使用static_cast 办到;此外add
函数传参时也会调用operator int 进行转换。
二、->运算符重载
类* operator->();
类& operator*();
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 void Open() void Close() void Query() class DB ~DB() DBHelper *operator->() DBHelper &operator*() int main(void) (*db).Open(); 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 则没有内存分配而是直接调用构造函数。下面看例子:
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 void operator delete(void *p) //与下面的operator delete函数类似,共存的话优先; void operator delete(void *p, size_t size) void *operator new(size_t size, const char *file, long line) void operator delete(void *p, const char *file, long line) void operator delete(void *p, size_t size, const char *file, long line) void operator delete(void *, void *) /*************** global **********************************************/ void *operator new(size_t size) void operator delete(void *p) void *operator new[](size_t size) void operator delete[](void *p) int main(void) char *str1 = new char; char *str2 = new char[100]; char chunk[10]; Test *p2 = new (chunk) Test(200); //operator new(size_t, void *_Where) //Test* p3 = (Test*)chunk; #define new new(__FILE__, __LINE__) 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++编程规范
类型转换运算符、*运算符重载、->运算符重载、operator new 和 operator delete的更多相关文章
- C++ Primer : : 第十四章 : 重载运算符与类型转换之类型转换运算符和重载匹配
类型转换运算符 class SmallInt { public: SmallInt(int i = 0) : val(i) { if (i < 0 || i > 255) throw st ...
- c/c++ 重载运算符 类型转换运算符
重载运算符 类型转换运算符 问题:能不能把一个类型A的对象a,转换成另一个类型B的对象b呢?? 是可以的.这就必须要用类型A的类型转换运算符(conversion operator) 下面的opera ...
- [C++ Primer] : 第14章: 重载运算符与类型转换
基本概念 重载运算符是具有特殊名字的函数: 它们的名字由关键字operator和其后要定义的运算符号共同组成. 重载运算符函数的参数数量与该运算符作用的运算对象数量一样多. 对于二元运算符来说, 左侧 ...
- 【C++】C++中重载运算符和类型转换
输入输出运算符 输入输出运算符 输入输出运算符 算术和关系运算符 相等运算符 关系运算符 赋值运算符 复合赋值运算符 下标运算符 递增和递减运算符 成员访问运算符 函数调用运算符 lambda是函数对 ...
- C++ Pirmer : 第十四章 : 重载运算符与类型转换之函数调用运算符与标准库的定义的函数对象
函数调用运算符 struct test { int operator()(int val) const { return (i > 0 ? i : -i); } }; 所谓的函数调用就是一个类重 ...
- C++ Primer : 第十四章 : 重载运算与类型转换之重载运算符
重载前须知 重载运算符是特殊的函数,它们的名字由operator和其后要重载的运算符号共同组成. 因为重载运算符时函数, 因此它包含返回值.参数列表和函数体. 对于重载运算符是成员函数时, 它的第一个 ...
- [置顶] operator overloading(操作符重载,运算符重载)运算符重载,浅拷贝(logical copy) ,vs, 深拷贝(physical copy)
operator overloading(操作符重载,运算符重载) 所谓重载就是重新赋予新的意义,之前我们已经学过函数重载,函数重载的要求是函数名相同,函数的参数列表不同(个数或者参数类型).操作符重 ...
- operator重载运算符
1.重载运算符的函数一般格式如下 函数类型 operator 运算符名称 (形参表列) {对运算符的重载处理} 例如,想将"+"用于Complex(复数)的加法运算, ...
- C++ operator重载运算符和隐式转换功能的实现
C++ operator重载运算符和隐式转换功能的实现: #include <iostream> using namespace std; class OperatorTest { pub ...
随机推荐
- Codeforces Round #247 (Div. 2) ABC
Codeforces Round #247 (Div. 2) http://codeforces.com/contest/431 代码均已投放:https://github.com/illuz/Wa ...
- 【资料】wod书籍
世界掉落 特点 风化的书卷 可用三次的无限耗材 华丽的书卷 可用5次 无限耗材 队伍唯一 抄录页:新手躲避 近远防御 +34%X技能等级 风化的书卷:新手躲避 华丽的书卷:新手躲避 抄录页:高级闪避技 ...
- android 各种颜色值 colors.xml
<?xml version="1.0" encoding="utf-8" ?> <resources> <color name=& ...
- 嵌入式Linux开发
嵌入式Linux的开发和研究是Linux领域研究的一个热点,目前已开发成功的嵌入式系统有一半以上都是Linux.Linux到底有什么优势,使之取得如此辉煌的成绩呢?本文分为两大部分:Linux的优点. ...
- 设计原则:小议 SPI 和 API
背景 第一次听说 SPI 是阅读<软件框架设计的艺术>,以后陆续在 Log4Net 和 Quartz.Net中发现了以这种形式组织代码的方式,本位给出为什么要区分 SPI 和 API 的一 ...
- C++ Tr1中的正則表達式
要使用正則表達式,首先要有类库支持,C++曾经不像Java或者C#有完整的类库使用,可是在Tr1中早已提供了正则库,仅仅是非常少被人们注意罢了 TR1中包括了一个正则库,来自Boost的 regex, ...
- webbrowser 常用方法(C#)
0.常用方法 Navigate(string urlString):浏览urlString表示的网址 Navigate(System.Uri url):浏览url表示的网址 Navigate(st ...
- Python学习(四)数据结构 —— dict
词典类型 dict 字典由键(key)和对应值(value)成对组成.字典也被称作关联数组或哈希表. dict 赋值 dict 整体放在花括号{}中,每个键与值用冒号隔开(:),每对用逗号分割: d ...
- 在Ubuntu 13.04下的安装eclipse
来源:http://www.cnblogs.com/lanxuezaipiao/p/3325628.html 一.eclipse安装过程 首先确保在安装eclipse之前已经安装好Java虚拟机 1. ...
- iOS: 沙盒的详解和目录的获取
沙盒的详解: •iOS应用程序只能在为该改程序创建的文件系统中读取文件,不可以去其它地方访问,此区域被称为沙盒 •iOS常用目录: –Bundle //该目录下的文件是用来存储应用程序包的 ...