C++

---恢复内容开始---

 

                            重载与多态

一:函数重载

 

重载函数是函数的一种特殊情况,为方便使用,C++允许在同一范围中声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不同,也就是说用同一个函数完成不同的功能。这就是重载函数。重载函数常用来实现功能类似而所处理的数据类型不同的问题。不能只有函数返回值类型不同。

 

前面博客以及讲过,不再赘述。。。

 

 

二:运算符重载

c++中预定义的运算符的操作对象只能是基本数据类型。实际上,对于很多用户自定义类型(比如类),同样也需要类似的操作。

     我在这里举一个非常经典例子,复数运算。

 

class Complex
{
public:
     Complex(double r=0.0,double i=0.0):real(r),imag(i){}
     void display() const;
private:
     double real;
     double imag;
};

 

 

     在这里我定义一个复数类,如果我们想要实现复数的加法的话,我们应该怎么办呢,我们首先想到的方法就是写一个函数,传进去两个Compex类作为参数,然后我们直接将成员相加就可以了,当然,我们也可以在类中写一个add函数,将complex作为其参数,但是这些方法显然比较麻烦,这时候我们需要引进运算符的重载,将+这个符号重载一下,使其能够实现复数的加法,到时候我们就可以直接同a+b一样去加两个类。
 
 

什么是运算符的重载?

         运算符与类结合,产生新的含义。 

为什么要引入运算符重载?

         作用:为了实现类的多态性(多态是指一个函数名有多种含义)

怎么实现运算符的重载?

方式:类的成员函数 或 友元函数(类外的普通函数)

规则:不能重载的运算符有 .  和 .* 和 ?: 和 ::  和 sizeof

友元函数和成员函数的使用场合:一般情况下,建议一元运算符使用成员函数,二元运算符使用友元函数

        1、运算符的操作需要修改类对象的状态,则使用成员函数。如需要做左值操作数的运算符(如=,+=,++)

        2、运算时,有数和对象的混合运算时,必须使用友元

        3、二元运算符中,第一个操作数为非对象时,必须使用友元函数。如输入输出运算符<<和>>

具体规则如下:

运算符 建议使用
所有一元运算符 成员函数
= ( ) [ ]  -> 必须是成员函数
+= -= /= *= ^= &= != %= >>= <<= , 似乎带等号的都在这里了 成员函数
所有其它二元运算符, 例如: –,+,*,/ 友元函数
<< >> 必须是友元函数

 

2. 参数和返回值

     当参数不会被改变,一般按const引用来传递(若是使用成员函数重载,函数也为const).

     对于返回数值的决定:

     1) 如果返回值可能出现在=号左边, 则只能作为左值, 返回非const引用。

     2) 如果返回值只能出现在=号右边, 则只需作为右值, 返回const型引用或者const型值。

     3) 如果返回值既可能出现在=号左边或者右边, 则其返回值须作为左值, 返回非const引用。

运算符重载举例:

+和 -运算符的重载:

class Point  
{  
private:  
    int x; 
public:  
    Point(int x1)
    {      x=x1;}  
    Point(Point& p)   
    {      x=p.x;}
    const Point operator+(const Point& p);//使用成员函数重载加号运算符
    friend const Point operator-(const Point& p1,const Point& p2);//使用友元函数重载减号运算符
};  

const Point Point::operator+(const Point& p)
{
    return Point(x+p.x);
}

Point const operator-(const Point& p1,const Point& p2)
{
    return Point(p1.x-p2.x);
}

 

三.虚函数

虚函数是一种在基类定义为virtual的函数,并在一个或多个派生类中再定义的函数。虚函数的特点是,只要定义一个基类的指针,就可以指向派生类的对象。

注:无虚函数时,遵循以下规则:C++规定,定义为基类的指针,也能作指向派生类的指针使用,并可以用这个指向派生类对象的指针访问继承来的基类成员;但不能用它访问派生类的成员。

1.使用虚函数实现运行时的多态性的关键在于:必须通过基类指针访问这些函数。

2. 一旦一个函数定义为虚函数,无论它传下去多少层,一直保持为虚函数。

 

纯虚函数:是定义在基类中的一种只给出函数原型,而没有任何与该基类有关的定义的函数。纯虚函数使得任何派生类都必须定义自己的函数版本。否则编译报错。

l纯虚函数定义的一般形式:

Virtual type func_name(参数列表)=0;

l  含有纯虚函数的基类称为抽象基类。抽象基类又一个重要特性:抽象类不能建立对象。但是抽象基类可以有指向自己的指针,以支持运行时的多态性。

#include<iostream>
#include<string>
 
using namespace std;
 
class Student
{
    public:
        Student(int , string, float);
        void display();
    protected:
        int num;
        string name;
        float score;    
};
Student::Student(int n, string na, float s)
{
    num=n;
    name=na;
    score=s;
}
void Student::display()
{
    cout<<"num:"<<num<<"\nname:"<<name<<"\nscore:"<<score<<endl;
}
class Graduate:public Student
{
    public:
            Graduate(int , string , float, float);
            void display();
 
    private:
            float pay;
    
};
Graduate::Graduate(int n, string na, float s, float p):Student(n,na,s),pay(p)
{
}
void Graduate::display()
{
    cout<<"num:"<<num<<"\nname:"<<name<<"\nscore:"<<score<<"\npay:"<<pay<<endl;
 }
 
int main()
{
    Student stud1(110,"SDL",99.8);
    Graduate grad1(120,"CCT",88.9, 250.5);
    
    Student *p;
    
    p=&stud1;
    cout<<"student:"<<endl;
    p->display();
    p=&grad1;
    cout<<"graduate:"<<endl;
    p->display();
    
    return 0;
}

 

运行截图:

 

 

 


-恢复内容结束---

---恢复内容结束---

posted @ 2019-10-27 19:01  ****l****  阅读(660)  评论(0编辑  收藏  举报