一,操作符重载
(1). 可重载的操作符
先来看看 C++中可以被重载的操作符有哪些
| + | - | * | / | % |
| ^ | & | | | ~ | ! |
| = | > | < | += | -= |
| *= | /= | %= | ^= | &= |
| |= | >> | << | >>= | <<= |
| == | != | >= | <= | && |
| || | ++ | -- | ->* | -> |
| [] | () | , (逗号) | ||
|
operator new
|
operator new[]
|
operator delete
|
operator delete []
| ------------- |
(2). 重载 + 操作符
使用 关键字 operator 关键字定义重载,这里先做一个简单的加法重载
class
Example
{
public
:
int
num;
public
:
Example( ) : num ( 10 ) { }
Example
operator + (
const
Example
&
ex)
const
{
Example
temEx;
temEx.num = num +
ex
.num;
return
temEx;
}
};
int
_tmain
(
int
argc,
_TCHAR*
argv
[])
{
Example
exA;
exA = exA + exA;
cout << exA.num << endl;
// 20
int
num;
cin>>num;
return
0;
};
当然,也可以直接将该
operator + 定义为 全局函数(非类成员函数).
Example
operator + (
const
Example
&
exA,
const
Example
&
exB)
{
Example
temEx;
temEx.num =
exA.num +
exB
.num;
return
temEx;
}
需要注意:
像上边这样返回已创建的值类型对象,会产生临时对象,但现在大多数编译器编译时会自动优化去除临时对象。要了解具体优化方法可搜索关键字 RVO 和 NRVO。
(3). operator() -- 仿函数 ( function object )
重载操作符 () 后,可以将类当函数调用 ,如
class
TestClass
{
public:
void
operator() (
const
string
str)
const
{
cout << str << endl;
}
};
void main()
{
TestClass test;
test(
"测试");
// == test.operator()("测试");
}
仿函数不但具有函数的特性,而且还可以保存状态(有自己的成员),所以更加灵活
(4). 扩展--神奇的连续调用
在某些C++库里会看到这样的语法 object ( ) ( ) ( ) ( ); 不使用点操作符亦可以连续调用, 这种效果也是 operator() 的"功劳"
class
TestClass
{
public :
TestClass& operator() (
const
char *
str)
const
{
cout <<
str << endl;
return *
this ;
}
};
int
_tmain (
int
argc,
_TCHAR*
argv [])
{
TestClass test;
test (
"测试") (
"测试2" ) (
"测试3" ) (
"测试4");
}
(5). operator 类型名() -- 类型重载
当一个类需要能够转换 (隐式) 成另一种类型的功能时,可以使用
- operator [类型] ()
的方式定义类型重载
class
Extras
{
public
:
int
x;
Extras( ) : x( 0 ) { };
};
class
Example
{
public
:
int
num;
public
:
Example( ) : num ( 10 ) { }
operator Extras ()
{
Extras
ex;
ex.x =
this
->num;
return
ex;
}
};
int
_tmain
(
int
argc,
_TCHAR*
argv
[])
{
Example
exA;
Extras ext = exA;
return
0;
};
二,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,既 对象的大小。示例如下:
void
* operator new(
size_t
size)
{
void* p = malloc(
size
);
cout <<
"重载 new: "
<< p << endl;
return
p;
}
int
_tmain
(
int
argc,
_TCHAR*
argv
[])
{
int
*pint =
new
int
;
return
0;
};
(2). 单独调用 operator new
也可以只调用 operator new ,而不调用对象的构造函数。示例如下:
class
Example
{
public
:
int
num;
public
:
Example( ) : num ( 1010 ) { }
};
void
*
operator new(
size_t
size)
{
void* p = malloc(
size
);
cout <<
"operator new : "
<< p << endl;
return
p;
}
extern
void
operator delete(
void*
p)
{
cout <<
"operator delete : "
<<
p
<< endl;
free(
p);
}
int
_tmain
(
int
argc,
_TCHAR*
argv
[])
{
Example
*exB = (
Example
*)
::operator new( sizeof( Example ) );
cout <<
"exB.num: "
<< exB <<
" | "
<< exB->num << endl;
:: operator delete (exB);
return
0;
};
总结:
- 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 )
示例如下(上一个示例的扩展)
int
_tmain
(
int
argc,
_TCHAR*
argv
[])
{
Example
*exB = (
Example
*)::
operator
new(
sizeof(
Example
) );
new
(exB)
Example
;
// 创建对象
//如果实例有析构函数时需要手动调用,如 exB->~Example();
cout <<
"exB.num: "
<< exB <<
" | "
<< exB->num << endl;
::
operator
delete
(exB);
return
0;
};
总结:
- placement new 函数,只是调用构造函数在已分配的内存中创建对象,而本身不分配内存。
- 使用 placement new 函数 创建对象,需销毁时,如果该对象有析构函数,需要在释放内存前显示调用。
-
<原创文章 转载请注明出处 http://blog.csdn.net/meiwm 谢谢>
出处:
http://blog.csdn.net/meiwm
本文为原创,本文版权归作者所有。欢迎转载,但请务必保留此段声明,且在文章页面明显位置给出原文连接,谢谢合作。
-
本文详细介绍了C++中的操作符重载概念及其应用,包括算术操作符、仿函数、类型转换操作符及new操作符的重载实现。通过实例展示了如何定制类的行为以符合特定需求。

927

被折叠的 条评论
为什么被折叠?



