c2665 “initgraph”: 2 个重载中没有一个可以转换所有参数类型_C++ 运算符重载

这一篇介绍C++中非常重要的一部分知识——运算符重载

如有侵权,请联系删除,如有错误,欢迎大家指正,谢谢

运算符重载

  • 运算符重载的作用是赋予运算符自定义功能,如 ‘ + ’ 号可以实现 ‘常数+常数’ 等常规的加法运算,但是对于 ‘对象+对象’ 、‘对象+常数’ 、‘常数+对象’ 等操作在默认情况下不被允许,但是可以通过重载 ‘ + ’ 实现这些运算
  • 形式为:返回值类型 operator运算符(参数列表);
  • 参数列表中必须有一个类类型的参数(最好是引用,避免进行拷贝构造)
  • 在类内进行运算符重载,参数列表中默认左边有一个所在类类型的参数,这个也比较好理解,类中的非静态成员函数左边都默认有一个所在类类型的参数(this指针,上一篇有介绍),运算符重载是一种特殊的函数,又是在类内进行重载的,所以它也有一个所在类类型的参数(this指针)
  • 不是所有的运算符都支持重载,支持重载的运算符又分为支持类内和类外重载(有些运算符既可以在类内重载也可以在类外重载,但有些运算符只可以在类内(类外)重载)

重载规则

《C++ Primer(第5版)》中给出的可重载和不可重载运算符

e6e57c6594859310ee3327b51f12ca7b.png
  • 赋值" = "、下标" [ ] "、调用"( )"和成员访问"->"运算符必须是成员
  • 复合赋值运算符(如:+= 等)一般来说应该是成员,但并非必须,这一点与赋值运算符略有不同
  • 改变对象状态的运算符或者与给定类型密切相关的运算符,如递增、递减和解引用运算符,通常应该是成员
  • 具有对称性的运算符可能转换为任一端的运算对象,例如算术、相等性、关系和位运算符等,因此它们通常应该是普通的非成员函数

一般运算符重载

#include <iostream>
using namespace std;

class Test {
public:
    Test(int n) : m(n) {

    }

    // ========= 类内和类外都可以重载,并且可以同时存在 ========
    // 类内重载"+(加)"运算符(类内类外可以同时存在)
    // "-(减)"、"*(乘)"、"/(除)"、"%(取余)"、"^(异或)"、"&(按位与)"、"|(按位或)"、
    // ">(大于)"、"<(小于)"、">=(大于等于)"、"<=(小于等于)"、"==(等于)"、"!=(不等于)"
    // "&&(与)"、"||(或)"与"+(加)"、
    // """"类似
    Test* operator+(int n) {
        Test* tmp = new Test{ *this };
        tmp->m += n;
        cout << tmp->m << endl;
        return tmp;
    }

    // ======== 类内类外都可以重载,不允许同时存在 ========
    // 类内重载"~(按位取反)"运算符(类内类外不能同时存在)
    // "+(正)"、"-(负)"、"!(非)"、"%(取余)"、"^(异或)"、"&(按位与)"、"|(按位或)"
    // "+=(加等于)"、"-=(减等于)"、"*=(乘等于)"、"/=(除等于)"、"%=(取余等于)"、"^=(异或等于)"、"&=(按位与等于)"、"|=(按位或等于)"
    // "<<=(左移等于)"、">>=(右移等于)"与"~(按位取反)"类似
    Test& operator~() {
        this->m = ~this->m;
        cout << this->m;
        return *this;
    }

    // ======== 只允许类内重载 ========
    // 类内重载"=(赋值)"运算符,只允许类内重载(这是拷贝赋值)
    // "[](下标运算符)"、"()(函数调用运算符,STL中的仿函数便是通过类内重载"()"实现的)"、"->(成员访问运算符)"
    Test& operator=(const Test& test) {
        this->m = test.m;
        return *this;
    }

    // "new"、"new[]"、"new()"、"delete"、"delete[]" 详细的重载方式在《C/C++内存申请和释放(二)》

    friend Test* operator+(const Test& test, int n); // 将类外重载"+(加)"运算符的函数声明为友元函数
    //friend Test& operator~(Test& test); // 将类外重载"~(按位取反)"运算符的函数声明为友元函数
private:
    int m;
};

// 类外重载"+(加)"运算符("-(减)"、"*(乘)"、"/(除)"、"%(取余)"、"^(异或)"与"+(加)"类似)
Test* operator+(const Test& test, int n) {
    Test* tmp = new Test{ test };
    tmp->m += n;
    cout << tmp->m << endl;
    return tmp;
}

//Test& operator~(Test& test) {
//  test.m = ~test.m;
//  cout << (test.m) << endl;
//  return test;
//}

int main() {
    Test test(2);
    Test* t1 = test + 2; // 调用重载的"+"
    delete t1;
    Test& t2 = ~test; // 调用重载的"~"
    Test t3(3);
    t3 = test;  // 调用重载的"=",传说中的拷贝赋值
    system("pause");
    return 0;
}

特殊运算符重载

  • cout 是 class ostream 的对象,cin 是 class istream 的对象,这两个只能在类外重载,因为 << 作用在左边的 cout 上,>> 作用在左边的 cin 上,类内重载函数默认最左边有一个参数是当前类的指针,将 cout 和 cin 传入类内重载的函数会发生冲突
class Test {
public:
    int n;

    Test(int n)
        : n(n) {

    }
};

ostream& operator<<(ostream& os, const Test& test) {
    return os << test.n;
}

Test test(2);
cout << test << endl;
  • 重载++(自加)、--(自减)运算符,类内重载和类外重载不允许同时存在
class Test {
public:
    Test(int n)
        : n(n) {

    }
    // 前置++类内重载
    Test& operator++() {
        ++this->n;
        cout << this->n << endl;
        return *this;
    }
    // 后置++类内重载
    Test& operator++(int flag) {
        this->n++;
        cout << this->n << endl;
        return *this;
    }

    friend Test& operator++(Test& test);
    friend Test& operator++(Test& test, int flag);
private:
    int n;
};

// 前置++类外重载
//Test& operator++(Test& test) {
//  ++test.n;
//  cout << test.n << endl;
//  return test;
//}
// 后置++类外重载
//Test& operator++(Test& test, int flag) {
//  test.n++;
//  cout << test.n << endl;
//  return test;
//}

Test test(2);
++test; // 前置++
test++; // 后置++

转换函数(类型转换的重载)

  • C++ 提供了两种强制类型转换的方式,一种是 (int)a;另一种是 int(a),C 语言只提供一种 (int)a
  • 转换函数——没有显示返回类型,但是要写返回值(返回值类型就是要转换成的类型);必须定义成类的非静态成员函数,没有参数(有一个默认所在类的参数(this指针));不应该改变对象的内容,所以一般是const函数
class Test {
public:
    Test(int n, double d)
        : n(n), d(d) {

    }
    operator int() const {
        return this->n;
    }
    operator double() const {
        return this->d;
    }
private:
    int n;
    double d;
};

Test test(2, 3.4);
cout << int(test) << " " << (double)test << endl;

如果未特殊说明,以上测试均是在win10 vs2017 64bit编译器下进行的

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值