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; };
什么是运算符的重载?
运算符与类结合,产生新的含义。
为什么要引入运算符重载?
作用:为了实现类的多态性(多态是指一个函数名有多种含义)
怎么实现运算符的重载?
方式:类的成员函数 或 友元函数(类外的普通函数)
规则:不能重载的运算符有 . 和 .* 和 ?: 和 :: 和 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; }
运行截图:
-恢复内容结束---
---恢复内容结束---