您的位置:首页 > 编程语言 > C语言/C++

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
本文为原创,本文版权归作者所有。欢迎转载,但请务必保留此段声明,且在文章页面明显位置给出原文连接,谢谢合作。

-
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: