C++快速入门 (十二) 操作符重载
2013-02-10 19:02
357 查看
一,操作符重载
(1). 可重载的操作符
先来看看 C++中可以被重载的操作符有哪些+ | - | * | / | % |
^ | & | | | ~ | ! |
= | > | < | += | -= |
*= | /= | %= | ^= | &= |
|= | >> | << | >>= | <<= |
== | != | >= | <= | && |
|| | ++ | -- | ->* | -> |
[] | () | , (逗号) | ||
operator new | operator new[] | operator delete | operator delete [] | ------------- |
(2). 重载 + 操作符
使用 关键字 operator 关键字定义重载,这里先做一个简单的加法重载[align=left]class Example[/align]
[align=left]{[/align]
[align=left]public :[/align]
[align=left] int num;[/align]
[align=left]public :[/align]
[align=left] Example( ) : num ( 10 ) { }[/align]
[align=left] Example operator + ( const Example & ex) const[/align]
[align=left] {[/align]
[align=left] Example temEx;[/align]
[align=left] temEx.num = num + ex .num;[/align]
[align=left] return temEx;[/align]
[align=left] }[/align]
[align=left]};[/align]
[align=left]int _tmain (int argc, _TCHAR* argv [])[/align]
[align=left]{[/align]
[align=left] Example exA;[/align]
[align=left] exA = exA + exA;[/align]
[align=left] cout << exA.num << endl; // 20[/align]
[align=left] int num;[/align]
[align=left] cin>>num;[/align]
[align=left] return 0;[/align]
[align=left]};[/align]
当然,也可以直接将该 operator + 定义为 全局函数(非类成员函数).
[align=left]Example operator + (const Example & exA, const Example & exB)[/align]
[align=left]{[/align]
[align=left] Example temEx;[/align]
[align=left] temEx.num = exA.num + exB .num;[/align]
[align=left] return temEx;[/align]
[align=left]}[/align]
需要注意:
像上边这样返回已创建的值类型对象,会产生临时对象,但现在大多数编译器编译时会自动优化去除临时对象。要了解具体优化方法可搜索关键字 RVO 和 NRVO。
(3). operator() -- 仿函数 ( function object )
重载操作符 () 后,可以将类当函数调用 ,如[align=left]class TestClass[/align]
[align=left]{[/align]
[align=left]public:[/align]
void operator() (const string str) const
{
cout << str << endl;
[align=left] }[/align]
[align=left]};[/align]
[align=left]void main()[/align]
[align=left]{[/align]
[align=left] TestClass test;[/align]
[align=left] test( "测试"); // == test.operator()("测试");[/align]
[align=left]}[/align]
仿函数不但具有函数的特性,而且还可以保存状态(有自己的成员),所以更加灵活
(4). 扩展--神奇的连续调用
在某些C++库里会看到这样的语法 object ( ) ( ) ( ) ( ); 不使用点操作符亦可以连续调用, 这种效果也是 operator() 的"功劳"[align=left]class TestClass[/align]
[align=left]{[/align]
[align=left]public :[/align]
[align=left] TestClass& operator() ( const char *str) const[/align]
[align=left] {[/align]
[align=left] cout << str << endl;[/align]
[align=left] return *this ;[/align]
[align=left] }[/align]
[align=left]};[/align]
[align=left]int _tmain (int argc, _TCHAR* argv [])[/align]
[align=left]{[/align]
[align=left] TestClass test;[/align]
[align=left] test ("测试") ( "测试2" ) ("测试3" ) ("测试4");[/align]
[align=left]}[/align]
(5). operator 类型名() -- 类型重载
当一个类需要能够转换 (隐式) 成另一种类型的功能时,可以使用operator [类型] ()
的方式定义类型重载
[align=left]class Extras[/align]
[align=left]{[/align]
[align=left]public :[/align]
[align=left] int x;[/align]
[align=left] Extras( ) : x( 0 ) { };[/align]
[align=left]};[/align]
[align=left]class Example[/align]
[align=left]{[/align]
[align=left]public :[/align]
[align=left] int num;[/align]
[align=left]public :[/align]
[align=left] Example( ) : num ( 10 ) { }[/align]
[align=left] operator Extras ()[/align]
[align=left] {[/align]
[align=left] Extras ex;[/align]
[align=left] ex.x = this ->num;[/align]
[align=left] return ex;[/align]
[align=left] }[/align]
[align=left]};[/align]
[align=left]int _tmain (int argc, _TCHAR* argv [])[/align]
[align=left]{[/align]
[align=left] Example exA;[/align]
[align=left] Extras ext = exA;[/align]
[align=left] [/align]
[align=left] return 0;[/align]
[align=left]};[/align]
二,operator new 重载
(1). new expression 和 operator new
C++中 new 一个对象会做两件事调用某个 operator new 分配足够存储对象的内存空间
调用该对象的构造函数
而 new 操作符是不可以重载,但其用来分配空间的 operator new 函数却可以被重载的。operator new 函数的签名如下:
void* operator new(size_t size)
重载 operator new 时,可以使用 n 个参数,但 第一个参数 必须是 size_t,既 对象的大小。示例如下:
[align=left]void * operator new(size_t size)[/align]
[align=left]{[/align]
[align=left] void* p = malloc( size );[/align]
[align=left] cout << "重载 new: " << p << endl;[/align]
[align=left] return p;[/align]
[align=left]}[/align]
[align=left]int _tmain (int argc, _TCHAR* argv [])[/align]
[align=left]{[/align]
[align=left] int *pint = new int ;[/align]
[align=left] return 0;[/align]
[align=left]};[/align]
(2). 单独调用 operator new
也可以只调用 operator new ,而不调用对象的构造函数。示例如下:[align=left]class Example[/align]
[align=left]{[/align]
[align=left]public :[/align]
[align=left] int num;[/align]
[align=left]public :[/align]
[align=left] Example( ) : num ( 1010 ) { }[/align]
[align=left]};[/align]
[align=left]void * operator new(size_t size)[/align]
[align=left]{[/align]
[align=left] void* p = malloc( size );[/align]
[align=left] cout << "operator new : " << p << endl;[/align]
[align=left] return p;[/align]
[align=left]}[/align]
[align=left]extern void operator delete( void* p)[/align]
[align=left]{[/align]
[align=left] cout << "operator delete : " << p << endl;[/align]
[align=left] free( p);[/align]
[align=left]}[/align]
[align=left]int _tmain ( int argc, _TCHAR* argv [])[/align]
[align=left]{[/align]
Example *exB = ( Example *) ::operator new( sizeof( Example )
);
[align=left] cout << "exB.num: " << exB << " | " << exB->num << endl;[/align]
[align=left] :: operator delete (exB);[/align]
[align=left] return 0;[/align]
[align=left]};[/align]
总结:
operator new 申请的内存可用 operator delete 释放。
如果在类中重载的 operator new 和 operator delete 均会变成(隐式)静态成员函数,
new 操作符 默认只会调用单个参数的 operator new 重载,如果有多个参数,则需要显式调用 operator new。
(3). placement new 函数
当需要在已分配的内存空间上创建对象时, 就需要使用 placement new,其签名如下:void *operator new( size_t, void *p )
示例如下(上一个示例的扩展)
[align=left]int _tmain ( int argc, _TCHAR* argv [])[/align]
[align=left]{[/align]
Example *exB = ( Example *)::operator new( sizeof( Example )
);
[align=left] new (exB) Example ; // 创建对象[/align]
[align=left] //如果实例有析构函数时需要手动调用,如 exB->~Example(); [/align]
[align=left] cout << "exB.num: " << exB << " | " << exB->num << endl;[/align]
[align=left] :: operator delete (exB);[/align]
[align=left] [/align]
[align=left] return 0;[/align]
[align=left]};[/align]
总结:
placement new 函数,只是调用构造函数在已分配的内存中创建对象,而本身不分配内存。
使用 placement new 函数 创建对象,需销毁时,如果该对象有析构函数,需要在释放内存前显示调用。
-
<原创文章 转载请注明出处 http://blog.csdn.net/meiwm 谢谢>
作者:meiwm
出处:http://blog.csdn.net/meiwm
本文为原创,本文版权归作者所有。欢迎转载,但请务必保留此段声明,且在文章页面明显位置给出原文连接,谢谢合作。
-
相关文章推荐
- 静态属性和静态方法 - C++快速入门21
- Microsoft Visual C++ 2005快速入门
- 复杂的数据类型5 - C++快速入门11
- c++快速简易入门教程_001从结构体到类
- c++快速简易入门教程_009引用
- SuperMap iObjects C++之MFC快速入门
- 高级强制类型转换 - C++快速入门37
- 命名空间和模块化编程3 - C++快速入门41
- 静态属性和静态方法2 - C++快速入门22
- 链接和作用域 - C++快速入门42
- 错误处理和调试 - C++快速入门30
- C++快速入门
- C++快速入门-命名空间
- 《算法笔记》2.7小节——C/C++快速入门->指针
- C++快速入门 (二) 变量和运算符
- 内联模板 - C++快速入门46
- 继承机制中的构造器和析构器 - C++快速入门17
- 访问控制 - C++快速入门18
- C++快速入门 (十三) 继承和多态
- 【C/C++】之C/C++快速入门