C++ 运算符重载、智能指针

运算符函数

在C++中会把运算符当作函数处理,一个表达式其实是调用了运算符函数完成计算的,这种特性对内建的数据类型没什么用,但对自建的数据类型却可以提高它们的个性化,从而提高代码的易用性和可读性,如:
    string str;
    str += "hehe";
    str == "xixi";

运算符格式

运算符格式:
单目运算符:#0、0#会被编译器翻译成如下形式
成员函数:
返回值 类名::operator<运算符>(参数)
{

}
全局函数:
返回值 operator<运算符>(类名&,参数)
{

}
注意:运算符的成员函数和全局函数只能实现一个,否则会冲突。

双目运算符:a#b(以左边的类型为主)
成员函数:
返回值 A:: operator#(const B&b)
{
	
}
全局函数:
返回值 operator#(const A& a,const B& b)
{
	
}

双目运算符重载

成员函数:a+b
const T operator+(const T& b)[const]
{
    T tmp(this->成员+b.成员);
    return tmp;
}

全局函数:a+b
const T operator+(const T& a,const T& b)
{
    T tmp(a.成员+b.成员);
    return emp;
}
注意:如果在全局函数使用到了类的私有成员,可以给全局函数加上友元声明(前加friend),这样该函数就可以使用类的私有成员。
注:如果全局和成员都重载了,那么会冲突。

输入、输出运算符重载

输出、输入运算符重载:
friend ostream& operator<<(ostream& os,const T& t)
{
    return os << t.xxx;
}
friend istream& operator>>(istream& is,T& t)
{
    return is >> t.xxx;
}

注意:由于双目运算符是由左边运算对象触发成员运算符,所以如果想把<<,>>运算符重载为成员运算符函数则必须在ostream、istream类的代码,但这两个类的代码已经封装在C++的的标准库中无法修改,所以必须重载为全局函数。

注意:友元不是成员函数(友元函数虽然在类中声明,但是属于全局),没有this指针,所以必须通过对象.成员函数。

自变运算符重载

前自变运算符:++/--i
    成员函数:
    const T& operator++(void)
    {
    	t.xxx++;
         return *this;
    }
    全局函数:
    const T& operator++(T& t)
    {
        t.xxx++;
        return t;
    }
后自变运算符:i++/--
    成员函数:
    const T operator++(int)
    {
        T t = *this;
        this->xxx++;
        return t;
    }
    全局函数:
    const T operator++(T& t,int)
    {
        t.xxx++;
        return t;
    }
    注意:用哑元(指参数里面的那个光秃秃的int)区别后自变运算符函数。

特殊运算符的重载

1、<< >> 既可以重载为输入输出,也可以重载为左移和右移。
2、->间接成员访问运算符/ *解引用运算符
    重载这两个运算符的目的是为了让对象可以像指针一样使用。
3、[] 下标运算符
    重载该运算符的目的是为了让对象像数组一样使用。
4、() 函数调用运算符
    重载该运算符的目的是为了让对象像函数一样使用。
5、new/delete重载
    1、new/delete重载后,可以在重载函数中记录分配、和释放的内存地址,用于检查 内存泄漏。
    2、对于分配的字节数据较小的内存块,可以在原来的基础上多分配一些,尽量减少内存碎片的产生,但同时也会浪费一部分内存。
    3、重载为成员和全局函数的格式相同,只是作用范围不同
        重载为成员函数,只有该类可以用。
        重载为全局函数,所有类型都可以使用。
    void* operator new(size_t len)
    {
        // len = len<8 ? 8 : len; 减少内存碎片的产生
        void* ptr = malloc(len);
        cout << "malloc:" << ptr << endl;
        return ptr;
    } 

    void operator delete(void* ptr)
    {
        free(ptr);
        cout << "free:" << ptr << endl;
        ptr = NULL;
    }

运算符重载的限制

1、不能重载的运算符
    :: 域限定符
    . 直接成员访问运算符
    ?: 三目运算符
    sizeof 字节数运算符
    typeid 类型信息运算符
2、只能重载为全局函数的运算符
    >> 输入运算符
    << 输出运算符
3、只能重载为成员函数的运算符
    [] 下载运算符
    = 赋值运算符
    -> 间接成员访问运算符
4、运算符重载时可以自定义运算符函数的计算过程,但无法改变运算符的优先级。
5、无法改变运算符的操作对象的个数。
6、不能发明新的运算符。

注意:
1、重载运算符要符合情理。
1、重载运算符时要遵循一致性,不要改变运算符的运算规则。
2、重载运算符是为了提高代码的可读性、易用性。

智能指针

常规指针的缺点:
    当常规指针离开它的作用域时,该指针所占用4|8字节的内存会被释放,而指针所指向堆内存可能,忘记执行free、delete、delete[],或者条件判断出现问题无法执行,这样就会导致内存泄漏。
    
什么智能指针:
    智能指针就是封装了常规指针的类对象,并且选项*,->运算符。
    当智能指针离开作用域时,会自动调用它的析构函数,在析构函数中释放常规指针所指向的堆内存,从而避免内存泄漏。

智能指针的缺点:
    1、不能跨作用域使用
    2、不能多个指针指向一个对象
    3、不能指向数组型对象
    4、不能放入容器

C++中智能指针的使用方法:C++98
    #include <memory>
    auto_ptr<类型> ptr(new 类型);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值