zoukankan      html  css  js  c++  java
  • 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 ),因为并不是成员函数,所以只是返回的类型是这个类型,而形参表中首先必须要有自定义的类型,就像调用一个函数一样

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

  • 相关阅读:
    【Leetcode】【Easy】Remove Duplicates from Sorted List
    【Leetcode】【Easy】Pascal's Triangle II
    【Leetcode】【Easy】Pascal's Triangle
    【Leetcode】【Easy】Binary Tree Level Order Traversal II
    【Leetcode】【Easy】Binary Tree Level Order Traversal
    【Leetcode】【Easy】Maximum Depth of Binary Tree
    【Leetcode】【Easy】Minimum Depth of Binary Tree
    【Leetcode】【Easy】Balanced Binary Tree
    【Leetcode】【Easy】Symmetric Tree
    如何使用Action.Invoke()触发一个Storyboard
  • 原文地址:https://www.cnblogs.com/working-in-heart/p/12131285.html
Copyright © 2011-2022 走看看