2021—研一学习笔记 day9

本文详细介绍了C++中的运算符重载,包括一元运算符、二元运算符、关系运算符、输入/输出运算符的重载,并通过实例展示了如何实现。此外,还讲解了C++的多态性,特别是虚函数的概念和使用,以及静态多态和动态多态的区别。
摘要由CSDN通过智能技术生成

2021-3-22 第九天

C++内容学习

w3school -> C++ -> 面向对象

网址:https://www.w3cschool.cn/cpp/cpp-data-structures.html

三)C++重载运算符和重载函数

允许在同一作用域中的某个函数和运算符指定多个定义
#但是它们的参数列表和定义(实现)不相同

当调用重载函数/运算符时,编译器会进行比较,选择最合适的定义。

C++中函数重载

可声明几个功能类似的同名函数,但这些同名函数的形参必须不同(参数的个数、类型或顺序)

例:
void print(int i){
cout<<"Printing int : "<<i<<endl;
}

void print(double f){
cout<<"Printing float : "<<f<<endl;
}

void print(char* c){
cout<<"Printing character : "<<c<<endl;
}

C++中运算符重载

大部分C++内置的运算符1都可以重定义或重载

重载运算符是带有特殊名称的函数,由operator+要重载的运算符组成
例:
Box operator+(const Box&);

//声明加法运算符,用于Box对象间的相加

不可重载的运算符列表:
①:: ②.* ③. ④?:

运算符重载的分类:

  • 一元运算符重载
  • 二元运算符重载
  • 关系运算符重载
  • 输入/输出运算符重载
  • ++和—运算符重载
  • 赋值运算符重载
  • 函数调用运算符()重载
  • 下标运算符[]重载
  • 类成员访问运算符->重载

1、一元运算符重载

只对一个操作数进行操作
如: ++、–、负号(-)、逻辑非(!)

例:

#include <iostream>
using namespace std;

class Distance{
public:
    Distance(){
        feet = 0;
        inches = 0;
    }
    Distance(int f, int i):feet(f), inches(i){}
    Distance(const Distance &c){
        feet = c.feet;
        inches = c.inches;
    }
    Distance operator-(){
        Distance d;
        d.feet = -feet;
        d.inches = inches;
        return d;
    }
    Distance operator-(const Distance& d){
        Distance dis;
        dis.feet = feet - d.feet;
        dis.inches = inches - d.inches;
        cout<<"my feet:"<<feet<<endl;
        cout<<"its feet:"<<d.feet<<endl;
        return dis;
    }
    ~Distance(){}
    int C(){
        return feet*inches;
    }
    void show(){
        cout<<"feet:"<<this->feet<<"; inches:"<<this->inches<<endl;
    }
private:
    int feet;
    int inches;
};

int main()
{
    Distance d;
    Distance d1(3,4);
    Distance d2(d);
    Distance d3;

    d = -d1;
    d3 = d1 - d;
    cout<<"d3:"<<endl;
    d3.show();

    cout<<"d1.C():"<<d1.C()<<endl;
    cout<<"d2.C():"<<d2.C()<<endl;
    cout<<"d.C():"<<d.C()<<endl;

    return 0;
}

2、二元运算符重载

二元运算符需要两个参数,+、-、*、/ 等运算都属于二元运算符

Distance operator+(const Distance& d){
Distance distance;
Distance.feet = this->feet + d.feet;
Distace.inches = this->inches + d.inches;
return distance;
//this可省略

}
Distance d3 = d1 + d2;

#对d3的初始化过程,调用了对象d1中的重载加法运算
#因此+号前的第一个参数代入的是d1对象
#而重载加法运算中,括号里引用的参数,此时由+号后的d2对象代入
例:

#include <iostream>

using namespace std;
class Complex{
private:
    double m_real;
    double m_imag;
public:
    void show();
    friend istream &operator>>(istream &in, Complex &A){
        in >> A.m_real >> A.m_imag;
        return in;
    }
    friend ostream &operator<<(ostream &out, const Complex &A){
        out << A.m_real << "+" << A.m_imag << "i" ;
        return out;
    }
};

void Complex::show(){
    cout<<this->m_real<<"+"<<this->m_imag<<"i"<<endl;
}





int main()
{
    Complex c1, c2;
    cout<<"Please input the real and imag:";
    cin>>c1>>c2;
    cout<<"The output of the real and imag:";
    cout<<c1<<endl;
    cout<<c2<<endl;
    return 0;
}

#关系运算符
#< >号,一般返回true或false
#不再赘述

3、输入/输出运算符重载

可以重载流提取运算符>>,和流插入运算符<<,来操作用户自定义的数据类型

#如果把运算符重载声明为类的友元函数,就能不用创建对象而直接调用函数

用友元函数来表示

1)重载输入运算符>>
friend istream &operator>>(istream &in, complex &A){
in>>A.m_real>>A.m_imag;
return in;
}

2)重载输出运算符<<
friend ostream &operator<<(ostream &out, complex &A){
out<<A.m_real<<A.m_imag;

}

例:

#include <iostream>

using namespace std;
class Complex{
private:
    double m_real;
    double m_imag;
public:
    void show();
    friend istream &operator>>(istream &in, Complex &A){
        in >> A.m_real >> A.m_imag;
        return in;
    }
    friend ostream &operator<<(ostream &out, const Complex &A){
        out << A.m_real << "+" << A.m_imag << "i" ;
        return out;
    }
};

void Complex::show(){
    cout<<this->m_real<<"+"<<this->m_imag<<"i"<<endl;
}

int main()
{
    Complex c1, c2;
    cout<<"Please input the real and imag:";
    cin>>c1>>c2;
    cout<<"The output of the real and imag:";
    cout<<c1<<endl;
    cout<<c2<<endl;
    return 0;
}

4、()运算符重载

用于增强操作C++数组的功能

例:

#include <iostream>
#define SIZE 10
using namespace std;

class Safearray{
private:
    int arr[SIZE];
public:
    Safearray(){
        int i;
        for(i = 0;i < SIZE;i++){
            this->arr[i] = i;
        }
    }

    int &operator[](int i){
        if(i > SIZE){
            cout<<"索引超过最大值"<<endl;
            return arr[0];
        }
        return arr[i];
    }
};

int main()
{
    Safearray A;
    cout<<"A[2]的值为:"<<A[2]<<endl;
    cout<<"A[5]的值为:"<<A[5]<<endl;
    cout<<"A[12]的值为:"<<A[12]<<endl;
    return 0;
}

5、->类成员访问运算符重载

#暂时看不太懂

https://www.w3cschool.cn/cpp/class-member-access-operator-overloading.html

四)C++多态

例:
//基类中有一个函数area(),派生类也有一个函数area()

Shape *shape;

Rectangle rec(10,7);
Triangle tri(10,5);

shape = &rec;
shape->area();

shape = &tri;
shape->area();

则,此时调用的area()函数为基类的area()函数
因为此时编译器看的是指针的类型。
这就是静态多态,或静态链接。

但,如果在基类Shape中,函数area()的声明前加上关键词virtual
则此时调用两个派生类的area()函数。

例:

#include <iostream>
using namespace std;

class Shape{
protected:
    int width;
    int depth;
public:
    Shape(int w, int d){
        width = w;
        depth = d;
    }
    virtual int area(){
        cout<< "Parent class area:" <<endl;
        return 0;
    }
};

class Rectangle:public Shape{
public:
    Rectangle(int w = 0, int d =0):Shape(w,d){}
    int area(){
        cout<< "Rectangle class area:" <<endl;
        return (width*depth);
    }
};

class Triangle:public Shape{
public:
    Triangle(int w = 0, int d =0):Shape(w,d){}
    int area(){
        cout<< "Triangle class area:" <<endl;
        return (width*depth/2);
    }
};

int main()
{
    Shape *shape;
    Rectangle rec(10,7);
    Triangle tri(10,5);

    rec.area();
    tri.area();

    shape = &rec;
    shape->area();

    shape = &tri;
    shape->area();

    return 0;
}

#此时,编译器看的是指针的内容,而不是它的类型
由于tri和rec类的对象的地址存储在*shape中,所以会调用派生类的area()函数

这种:每个子类都有一个函数area()的独立实现,这就是多态的一般使用方式。

有了多态,可以有多个不同的类,都带有同一名称但不同实现的函数。

虚函数:在基类中使用关键字virtual声明的函数

在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数。

这种操作被称为动态链接或后期绑定。

纯虚函数:不想对基类中的虚函数给出有意义实现
例:
class Shape{

virtual int area() = 0;
};

“=0”告诉编译器,函数没有主题,上面的虚函数是纯虚函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值