C++基础知识四

一、运算符重载
C++中是运算符当作函数来看待,所以C++中的运算符可以重载,这样可以让类对象支持运算符,对类对象进行定制化操作。
例如:string类就支持很多运算符来代替标准库中的函数。
= strcpy
+= strlen
==|!=|>=|<= strcmp

二、双目录运算符重载
假如:Test a,b; a+b操作可以调用两种函数
Test的成员函数:a是触发者,b是参数
Test operator+(cosnt Test& b) const
{
return a+b; // 返回临时对象
}

全局函数:a,b都是参数
Test operator+(const Test& a,const Test& b)
{
    return a+b; // 返回临时对象
}

注意:如果成员运算符函数和全局函数运算符函数都实现,调用时可能会产生二义性错误,成员或全局实现一个即可。

友元函数:
    在类外的函数想访问类的私有成员时,需要把函数声明类的友元函数,但友元函数只有朋友,只有访问权,没有实际的拥有权。
    
友元声明:
    把函数的声明在类中写一份,然后在函数的声明前加friend关键字。
    友元函数可以让运行符是全局函数,也可以保持类的封装性。

三、赋值类型的运算符
成员函数
Test& operator=(cosnt Test& b) // 隐藏的有
{
a = b;
return a;
}
全局函数
Test& operator=(Test& a,const Test& b) // a不能有const属性
{
a = b; // 返回临时对象
return a;
}
1、如果是某种类型直接为类对象赋值,单参构造也可以达到赋值运算符的效果。
String str = “hehe”; // 调用单参构造
str = “hehe”; // 赋值运算符
2、如果对象的成员中没有指针成员,默认的赋值函数即可。

四、输入输出运算符重载
使用输入输出运算符时由于触发运算符函数的是cout、cin,我们无法修改cont和cin的代码,所心只能实现为全局运算符函数。
ostream& operator<<(ostream& os,cosnt Test& t)
{
return os << t.m1 << t.m2;
}
istream& operator<<(istream& is,const Test& t)
{
return is >> t.m1 >> t.m2;
}
注意:外部的cin和cout可能需要连接的输入或输出因此需要把os和is返回,由于在输入输出过程中需要记录错误标志,因此不能加const。
五、单目运算符重载
~ ! ++ –
成员函数
Test operator!(void)
{
!this;
return Test(); // 返回临时对象
}
全局函数
Test operator!(Test& t)
{
!t;
return Test(); // 返回临时对象
}
前++/–
Test& operator++(void)
{
this++;
return *this;
}
Test& operator++(Test& t)
{

    }
后++/--
    Test operator++(int)// 哑元,为了区别前++/--
    {
        Test t = *this;
        this++;
        return t;
    } 

六、特殊运算符重载
1、下标运算符[],该运算符重载后可以让对象像数组一样使用,必须重载为成员函数。
2、解引用运算符*、成员访问运算符->,该运算符重载后可以让对象像指针一样使用。
3、函数调用运算符(),该运算符重载后可以让对象像函数一样使用。
4、new/delete/new[]/delete[]运算符重载
1、C++缺省的内存管理器速度比较慢,重载运算符可以使用malloc/free作为底层的内存管理器,提高运行速度。

    2、new运算在失败时会产生异常,而每次使用new时为了安全都就应该捕获异常,而重载new运算符后只需要在操作符函数中捕获一次并处理即可。

    3、一些字节数较少的类的对象,频繁使用new时会产生内存碎片,而重载new运算符后,可以适当的扩大申请的字节数,降低内存碎片产生的机率。

    4、重载new和delete后,可以函数中记录分配和释放的内存信息,方便查找内存泄漏。
    void* operator new(size_t size)
    {

    }

七、智能指针
常规指针的缺点:
当一个指针变量离开它的作用域,只有该指针所占用内存会被释放,而它指向的堆内存能否释放就不一定了,在一些特殊情况下
delete/free没有执行,就会造成内存泄漏。
智能指针的优点:
智能指针就是封装了常规指针的类类型对象,当它离开作用域时它的析构函数就会自动执行,
析构函数会负责释放常规指针所指向的堆内存。
auto_ptr:标准库中封装好模板类,实现了常规的基本功能。
头文件:#include
用法:auto_ptr<指向的类型> 指针变量名(new 类型);
之后就可以像常规指针一样使用智能指针了。
智能指针的缺点:
一个指针只能指向一个对象,但常规指针可以多个指针指向一个对象。
不能跨作用域使用,一但离开作用域智能指针就会释放它指向的对象。
智能指针不能放入容器中。
八、重载运算符的限制
1、只能重载为成员函数的运算符
= [] () -> *
2、只能重载为全局函数的运算符
<< >>
3、不能重载的运算符
:: 域限定符
. 直接成员访问运算符
?: 三目运算符
sizeof 字节数运算符
typeid 类型信息运算符
4、重载运算符时不能修改运算符的优先级。
5、重载运算符时不能改变参数的数量
6、无法为基本类型重载运算符
7、不能发明新的运算符

个人建议:
1、重载运算符时要根据运算符实际的功能和意义确定参数、返回值,是否使用const,不否使用引用,是否返回临时对象。

2、重载运行符时要符合情理、要有意义、以实际用途为前提。

3、重载运算符是为了让对象的操作更简单方便,提高代码可读性,而不是为了炫技。

4、重载运算符的功能要与默认的一致,不要出现反人类的操作。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值