• C++学习笔记之运算符重载


    双目运算符:

     1 #include <iostream>
     2 using namespace std;
     3 class Complex {
     4 public:
     5     Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) { } //默认构造函数虽说是默认,但是如果给了参数也能调用,是一个好习惯
     6     
     7     Complex operator+(const Complex& c2) const;//+
     8 
     9     Complex operator+(int& a) const;//复数和实数
    10     
    11     Complex operator - (const Complex& c2) const;//-
    12 
    13     void display() const;   //输出复数
    14 private:
    15     double real;    //复数实部
    16     double imag;    //复数虚部
    17 };
    18 
    19 Complex Complex::operator +(const Complex & c2) const { //复数+
    20     return Complex(real + c2.real, imag + c2.imag);
    21 }
    22 
    23 Complex Complex::operator +(int& a) const {//复数和实数+
    24     a++;
    25     return Complex(real + a, imag );
    26 }
    27 
    28 Complex Complex::operator-(const Complex& c2) const {//复数-
    29     return Complex(real - c2.real, imag - c2.imag);
    30 }
    31 
    32 void Complex::display() const {
    33     cout << "(" << real << ", " << imag << ")" << endl;
    34 }
    35 
    36 int main() {
    37     Complex c1(5, 4), c2(2, 10), c3;
    38     int b = 5;
    39     cout << "c1 = "; c1.display();
    40     cout << "c2 = "; c2.display();
    41     c3 = c1 - c2;   //使用重载运算符完成复数减法
    42     cout << "c3 = c1 - c2 = "; c3.display();
    43     c3 = c1 + c2;   //使用重载运算符完成复数加法
    44     cout << "c3 = c1 + c2 = "; c3.display();
    45     c3 = c1 + b;    //这里是复数和实数相加,注意(复数和int变量相加)和(复数直接加数c3=c1+5)的区别,后者编译器会把 5 当成复数再次生成一个复数类的对象,但是只有一个参数,也就是实部,然后进行复数类相加
    ,原因是写了默认的构造函数(上面黄色),我怀疑是加法函数的顺序问题,但试了一下,发现并不是,终究还是构造函数的问题,下面会给出后面这种方式的代码
    46 cout << "c3 = c1 + c2 = "; c3.display(); 47 return 0; 48 }

    想要让  c3=c1+5 调用的函数是复数+实数的代码(黄色是不用的地方):

     1 #include <iostream>
     2 using namespace std;
     3 class Complex {
     4 public:
     5     Complex() {};//默认构造函数,并不初始化赋值
     6     Complex(double r, double i) : real(r), imag(i) { } 
     7     
     8     Complex operator+(const Complex& c2) const;//+
     9 
    10     Complex operator+(int a) const;//复数和实数
    11     
    12     Complex operator - (const Complex& c2) const;//-
    13 
    14     void display() const;   //输出复数
    15 private:
    16     double real;    //复数实部
    17     double imag;    //复数虚部
    18 };
    19 
    20 Complex Complex::operator +(const Complex & c2) const { //复数+
    21     return Complex(real + c2.real, imag + c2.imag);
    22 }
    23 
    24 Complex Complex::operator +(int a) const {//复数和实数+
    25     a++;
    26     return Complex(real + a, imag );
    27 }
    28 
    29 Complex Complex::operator-(const Complex& c2) const {//复数-
    30     return Complex(real - c2.real, imag - c2.imag);
    31 }
    32 
    33 void Complex::display() const {
    34     cout << "(" << real << ", " << imag << ")" << endl;
    35 }
    36 
    37 int main() {
    38     Complex c1(5, 4), c2(2, 10), c3;//c3 调用默认构造函数,垃圾数据
    39     int b = 5;
    40     cout << "c1 = "; c1.display();
    41     cout << "c2 = "; c2.display();
    42     c3 = c1 - c2;   //使用重载运算符完成复数减法
    43     cout << "c3 = c1 - c2 = "; c3.display();
    44     c3 = c1 + c2;   //使用重载运算符完成复数加法
    45     cout << "c3 = c1 + c2 = "; c3.display();
    46     c3 = c1 + 5;
    47     cout << "c3 = c1 + c2 = "; c3.display();
    48     return 0;
    49 }

    虽然后面解决了这种问题,但是我也发现了这种直接通过对象 运算符重载计算 的漏洞,所以我强烈建议对象之间的操作不要直接通过数字,而是通过对象和对象的操作从而使得能够按照自己的想法运行,虽然直接通过数字可以,但是其构造函数明显是不合理的(因为默认构造函数并没有给默认参数,而是垃圾数据,C3就是例子)

     为了解决这种情况,我们提出了非成员函数解决这个问题(之前的方法是调用成员函数)那这两种方法有什么区别?

    如果要重载 B 为类成员函数,使之能够实现表达式 oprd1 B oprd2,其中 oprd1 为A 类对象,则 B 应被重载为 A 类的成员函数,形参类型应该是 oprd2 所属的类型。经重载后,表达式 oprd1 B oprd2 相当于 oprd1.operator B(oprd2),这里形参少一个,因为这个类的对象就是其中一个操作数

    而在非成员函数中:参数个数=原操作数个数,表达式oprd1 B oprd2,等同于operator B(oprd1,oprd2 ),因为并不是成员函数,所以只是返回的类型是这个类型,而形参表中首先必须要有自定义的类型,就像调用一个函数一样

    如果在运算符的重载函数中需要操作某类对象的私有成员,可以将此函数声明为该类的友元。

  • 相关阅读:
    For each db / table
    转---网络上来的,做一个数组样的结构
    JAVA 相关资料
    转--也不知是哪位大侠写的了
    T-SQL切割字符串方法小结 2
    OPENQUERY
    行集函数专题
    行列转换
    第一章 SQL基础
    解释型语言与编译型语言的区别
  • 原文地址:https://www.cnblogs.com/working-in-heart/p/12131285.html
Copyright © 2020-2023  润新知