一个类能够派生自多个类,这意味着,它能够从多个基类继承数据和函数。定义一个派生类,咱们使用一个类派生列表来指定基类。类派生列表以一个或多个基类命名,形式以下:ios
// 派生类 class Rectangle: public Shape { public: int getArea() { return (width * height); } };
多继承即一个子类能够有多个父类,它继承了多个父类的特性。程序员
C++ 类能够从多个类继承成员,语法以下:编程
class <派生类名>:<继承方式1><基类名1>,<继承方式2><基类名2>,… { <派生类类体> };
C++ 容许在同一做用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载。函数
重载声明是指一个与以前已经在该做用域内声明过的函数或方法具备相同名称的声明,可是它们的参数列表和定义(实现)不相同。this
当您调用一个重载函数或重载运算符时,编译器经过把您所使用的参数类型与定义中的参数类型进行比较,决定选用最合适的定义。选择最合适的重载函数或重载运算符的过程,称为重载决策。spa
在同一个做用域内,能够声明几个功能相似的同名函数,可是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不一样。您不能仅经过返回类型的不一样来重载函数。指针
#include <iostream> using namespace std; class printData { public: 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; } }; int main(void) { printData pd; // Call print to print integer pd.print(5); // Call print to print float pd.print(500.263); // Call print to print character pd.print("Hello C++"); return 0; }
您能够重定义或重载大部分 C++ 内置的运算符。这样,您就能使用自定义类型的运算符。对象
重载的运算符是带有特殊名称的函数,函数名是由关键字 operator 和其后要重载的运算符符号构成的。与其余函数同样,重载运算符有一个返回类型和一个参数列表。继承
Box operator+(const Box&);
// 重载 + 运算符,用于把两个 Box 对象相加 Box operator+(const Box& b) { Box box; box.length = this->length + b.length; box.breadth = this->breadth + b.breadth; box.height = this->height + b.height; return box; }
多态按字面的意思就是多种形态。当类之间存在层次结构,而且类之间是经过继承关联时,就会用到多态。接口
C++ 多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不一样的函数。
虚函数 是在基类中使用关键字 virtual 声明的函数。在派生类中从新定义基类中定义的虚函数时,会告诉编译器不要静态连接到该函数。
咱们想要的是在程序中任意点能够根据所调用的对象类型来选择调用的函数,这种操做被称为动态连接,或后期绑定。
您可能想要在基类中定义虚函数,以便在派生类中从新定义该函数更好地适用于对象,可是您在基类中又不能对虚函数给出有意义的实现,这个时候就会用到纯虚函数。
class Shape { protected: int width, height; public: Shape( int a=0, int b=0) { width = a; height = b; } // pure virtual function virtual int area() = 0; };
= 0 告诉编译器,函数没有主体,上面的虚函数是纯虚函数。
首先:强调一个概念
定义一个函数为虚函数,不表明函数为不被实现的函数。
定义他为虚函数是为了容许用基类的指针来调用子类的这个函数。
定义一个函数为纯虚函数,才表明函数没有被实现。
定义纯虚函数是为了实现一个接口,起到一个规范的做用,规范继承这个类的程序员必须实现这个函数。
一、简介
假设咱们有下面的类层次:
#include <iostream> using namespace std; class A { public: virtual void foo() { cout<<"A::foo() is called"<<endl; } }; class B:public A { public: void foo() { cout<<"B::foo() is called"<<endl; } }; int main(void) { A *a = new B(); a->foo(); // 在这里,a虽然是指向A的指针,可是被调用的函数(foo)倒是B的! return 0; }
运行结果:
B::foo() is called
这个例子是虚函数的一个典型应用,经过这个例子,也许你就对虚函数有了一些概念。它虚就虚在所谓“推迟联编”或者“动态联编”上,一个类函数的调用并非在编译时刻被肯定的,而是在运行时刻被肯定的。因为编写代码的时候并不能肯定被调用的是基类的函数仍是哪一个派生类的函数,因此被成为“虚”函数。
虚函数只能借助于指针或者引用来达到多态的效果
一、纯虚函数声明以下: virtual void funtion1()=0; 纯虚函数必定没有定义,纯虚函数用来规范派生类的行为,即接口。包含纯虚函数的类是抽象类,抽象类不能定义实例,但能够声明指向实现该抽象类的具体类的指针或引用。
二、虚函数声明以下:virtual ReturnType FunctionName(Parameter) 虚函数必须实现,若是不实现,编译器将报错,错误提示为:
error LNK****: unresolved external symbol "public: virtual void __thiscall ClassName::virtualFunctionName(void)"
三、对于虚函数来讲,父类和子类都有各自的版本。由多态方式调用的时候动态绑定。
四、实现了纯虚函数的子类,该纯虚函数在子类中就编程了虚函数,子类的子类即孙子类能够覆盖该虚函数,由多态方式调用的时候动态绑定。
五、虚函数是C++中用于实现多态(polymorphism)的机制。核心理念就是经过基类访问派生类定义的函数。
六、在有动态分配堆上内存的时候,析构函数必须是虚函数,但没有必要是纯虚的。
七、友元不是成员函数,只有成员函数才能够是虚拟的,所以友元不能是虚拟函数。但能够经过让友元函数调用虚拟成员函数来解决友元的虚拟问题。
八、析构函数应当是虚函数,将调用相应对象类型的析构函数,所以,若是指针指向的是子类对象,将调用子类的析构函数,而后自动调用基类的析构函数。