1.运算符重载
#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;//运算符+重载成员函数 void display() const; private: double real; double image; }; Complex Complex::operator+(const Complex &c2) const{ return Complex(real+c2.real,image+c2.image);//创建一个临时无名对象作为返回值 } void Complex::display() const{ cout<<"("<<real<<","<<image<<")"<<endl; }
2虚函数
如果需要通过基类的指针指向派生类的对象,并访问某个与基类同名的成员,那么首先在基类中将这个同名函数说明为虚函数。这样,通过基类类型的指针,就可以是属于不同派生类的不同对象产生不同的行为,从而实现运行过程的多态。
#include<iostream> using namespace std; class Base1{ public: virtual void display() const;//虚函数 }; void Base1::display() const{ cout<<"Base1::display()"<<endl; } class Base2:public Base1{ //共有派生类Base2定义 public: void display() const;//覆盖基类的函数 }; void Base2::display() const{ cout<<"Base2::display()"<<endl; } class Derived:public Base2{ public: void display() const;//覆盖基类的虚函数 }; void Derived:display() const{ cout<<"Derived::display()"<<endl; } void fun(Base1 * ptr){//参数为指向基类对象的指针 ptr->display();//“对象指针->成员名” }
只有虚函数是动态绑定的,如果派生类需要修改基类的行为(即重写与基类函数同名的函数),就应该在基类中将相应的函数声明为虚函数。而基类中声明的非虚函数,通常代表那些不希望被派生类改变的功能,也是不能实现多态的。一般不要重写继承而来的虚函数(虽然语法对此没有强制要求),应为那会导致通过基类指针和派生类的指针或对象调用同名函数式,产生不同的结果,从而引起混乱。只有通过基类的指针或引用调用虚函数时,才会发生动态绑定。
如果一个类的析构函数是虚函数,那么由他派生而来的所有子类的析构函数也是虚函数。
3.纯虚函数与抽象类
抽象类是一种特殊的类,他为一个类族提供统一的操作界面。可以说,建立抽象类,就是为了通过他多态地使用其中的成员函数。抽象类处于类层次的上层,一个抽象类自身无法实例化,也就是说我们无法顶第一个抽象类的对象,只能通过继承机制,生成抽象类的非抽象派生类,然后再实例化。声明为纯虚函数之后,基类中就可以不再给出函数的实现部分。
#include<iostream> using namespace std; class Base1{ public: virtual void display() const=0;//纯虚函数 }; class Base2:public Base1{ public: void display() const;//覆盖基类的虚函数 }; void Base2::display() const{ cout<<"Base2::display()"<<endl; } class Derived:public Base2{ public: void display() const;//覆盖基类的虚函数 }; void Derived:display(() const{ cout<<"Derived::display()"<<endl; } void fun(Base1 * ptr){ //参数为指向基类对象的指针 ptr->display(); //‘对象指针->成员名" }