多态与重载

Posted byp-520

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多态与重载相关的知识,希望对你有一定的参考价值。

多态和重载

一:多态

1:定义:多态是指同样的消息被不同类型的对象接收时导致的不同行为。

消息是指对类的成员函数的调用。不同行为是指不同的实现,即调用了不同的函数。

2:多态的类型:
1:专用多态 :

? 1:重载多态

? 2:强制多态

2:通用多态:

? 3:包含多态

? 4:参数多态

3:多态的实现:编译时的多态和运行时的多态

两者分别在编译过程中和运行过程中进行确定操作对象。

这种确定操作的具体对象又被称为绑定,即将一个的方法和一条消息进行结合的过程。

静态绑定:绑定工作在编译连接阶段完成的情况.eg:重载,强制和参数多态就通过静态绑定实现。

动态绑定:在程序运行阶段完成。

二:重载

接下来我们介绍运算符重载

1:定义:运算符重载是对已有的运算符赋予多重含义,使同一个运算符作用于不同类型的数据时导致不同的行为。
实质:函数重载。

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

(注意:1:有些运算符是不能进行重载的,eg:三目运算符“?:”,作用域分辨符“::”而且只能重载C++中已经有的运算符

? 2:运算符的优先级和结合性不会变)

这样,您就能使用自定义类型的运算符。

重载的运算符是带有特殊名称的函数,函数名是由关键字 operator 和其后要重载的运算符符号构成的。与其他函数一样,重载运算符有一个返回类型和一个参数列表。

Box operator+(const Box&);
2:运算符重载为成员函数和非成员函数

注意:当重载为类的成员函数时,函数的参数个数要比原来的操作数个数要少一个(后置“++”,“——”除外),重载为非成员函数时,操作个数相同。

a:重载为非成员函数

eg:双目运算符重载为成员函数

#include<iostream>

using namespace std;
class complex
{
public:
    complex(double r = 0.0, double i = 0.0) :real(r), imag(i) {}
    complex operator+(const complex& c2) const;//运算符+重载成员函数
    complex operator-(const complex& c2) const;//运算符-重载成员函数
    void display() const;
private:
    double real;
    double imag;
};
complex complex::operator+(const complex& c2) const
{
    return complex(real + c2.real, imag + c2.imag);//创建一个临时无名对象作为返回值
}
complex complex::operator-(const complex& c2) const
{
    return complex(real - c2.real, imag - c2.imag);
}
void complex::display() const
{
    cout << "(" << real << "," << imag << ")" << endl;
}
int main()
{
    complex c1(5, 4), c2(2, 10), c3;
    cout << "c1="; c1.display();
    cout << "c2="; c2.display();
    c3 = c1 - c2;//使用重载运算符完成复数减法
    cout << "c3=c1-c2="; c3.display();
    c3 = c1 + c2;
    cout << "c3=c1+c2="; c3.display();
    return 0;
}

技术图片

单目运算符重载为成员函数

eg:

#include<iostream>
using namespace std;
class clock
{
public:
    clock(int hour = 0, int minute = 0, int second = 0);
    void showtime() const;
    clock& operator++();
    clock operator++(int);
private:
    int hour, minute, second;
};
clock::clock(int hour, int minute, int second)
{
    if (0 <= hour && hour < 24 && 0 <= minute && minute < 60 && 0 <= second && second < 60)
    {
        this->hour = hour;
        this->minute = minute;
        this->second = second;
    }
    else
    {
        cout << "time error!" << endl;
    }
}
void clock::showtime() const
{
    cout << hour << ":" << minute << ":" << second << endl;
}
clock& clock::operator++()//前置单目运算符重载函数
{
    second++;
    if (second >= 60)
    {
        second -= 60;
        minute++;
        if (minute >= 60)
        {
            minute -= 60;
            hour = (hour + 1) % 24;
        }
    }
    return *this;
}
clock clock::operator++(int)//后置单目运算符重载
{
    clock old = *this;
    ++(*this);//调用前置“++”运算符
    return old;
}
int main()
{
    clock myclock(23, 59, 59);
    cout << "first time output: ";
    myclock.showtime();
    cout << "show myclock++   ";
    (myclock++).showtime();
    cout << "show ++myclock   ";
    (++myclock).showtime();
    return 0;
}

技术图片

注意:语法规定,前置单目重载为运算符时没有形参,而后置单目需要有一个int型的形参。
b:重载为非成员函数

注意:1:这时运算所需要的操作数都需要通过函数的形参表来传递。

2:若需要访问运算符参数对象的私有成员,可以将该函数声明我友元函数。

函数的使用方法:

重载双目运算符U: oprd1 U oprd2 = operator U (opad1,oprd2)

前置单目运算符U:Uoprd = operator U(oprd)

后置单目运算符U:oprd U = operator U(oprd, 0)
eg:

Complex operator -(Complex C1, Complex C2) 

{
Complex Temp;
Temp.Vector_x= C1.getVector_x()- C2.getVector_x();
Temp.Vector_y = C1.getVector_y() - C2.getVector_y();
return Temp;
}

总结:

重载简单来说重载为成语函数会更接简单一些,但有些情况需要使用重载为非成员函数。

eg:

1:要重载的操作符的第一个操作数不是可以更改的类型。

2:以非成员函数的形式重载,支持更灵活的形式转变。

以上是关于多态与重载的主要内容,如果未能解决你的问题,请参考以下文章

多态与重载

C++基础——C++面向对象之重载与多态基础总结(函数重载运算符重载多态的使用)

什么是多态方法重写与重载

每日一练---- 3.07 3.08 3.09oj总结(继承重载多态动态与静态绑定)

每日一练---- 3.07 3.08 3.09oj总结(继承重载多态动态与静态绑定)

详细说明:方法重载是静态/编译时绑定,但不是多态性。将静态绑定与多态性相关联是不是正确?