基本应用
#include <iostream>#include <string>using namespace std;class People{private:int age;private:string name;public:People(string name,int age){this->name = name;this->age = age; //this是一个指针,指向当前的对象}public: void println(){cout << "姓名为" << name << ",年纪为:" << age << endl;}};class Student:public People{//设置继承方式为publicpublic:Student(string name,int age):People(name,age){//继承父类的构造函数}};int main(){Student stu("小明",12);stu.println();return 0;}
继承方式
- 公共继承
- 保护继承
私有继承
公共继承 ```cpp class People{ };
class Student:public People{ //保留父类所有成员的访问权限 };
- 保护继承```cppclass People{};class Student:protected People{//保留父类protected及private的成员的访问权限//将父类所有public的成员修改为protected};
- 私有继承 ```cpp class People{ };
class Student:private People{ //所有父类的成员都修改为private };
<a name="q53GX"></a>###<a name="eVEOa"></a>### 访问与父类同名的变量及方法```java#include <iostream>#include <string>using namespace std;class People{public:void say(){cout << "People say" << endl;}public:static void go(){cout << "People go" << endl;}};class Student:public People{public:void say(){cout << "Student say" << endl;}public:static void go(){cout << "Student go" << endl;}};int main(){Student stu;stu.say();//调用Student中的成员函数saystu.People::say();//访问父类中的成员函数sayStudent::go();//调用Student中的静态函数goStudent::People::go();//访问父类中的静态函数goreturn 0;}
Student say People say Student go People go
一个类继承多个类
class People{};class Animal{};class Student:public People,public Animal{};
注:C++开发中不建议用多继承
多态及虚函数
多态的概念和Java是一样的,即允许父类和子类进行类型转换
#include <iostream>#include <string>using namespace std;class Animal{public://virtual为声明speak为虚函数virtual void speak(){cout << "动物在说话" << endl;};};class Dog:public Animal{public:void speak(){cout << "狗在说话" << endl;};};class Cat:public Animal{public:void speak(){cout << "猫在说话" << endl;};};void doSpeak(Animal& animal){animal.speak();}int main(){Cat cat;Dog dog;doSpeak(cat);doSpeak(dog);return 0;}
注:
- 如果不声明speak是虚函数(virtual),则执行doSpeak时,无论传参是Cat还是Dog,输出结果都会是Animal中的“动物在说话”
- 但在声明speak是虚函数以后,就会发现,在这种场景下,实际上父类的speak函数的实现是没有意义,那么这种场景下,可以把父类的speak修改为纯虚函数,即抽象函数。
纯虚函数及抽象类
如果一个类中有个纯虚函数,这个类就叫抽象类,其概念和特点其实和Java是一样的
class Animal{ public: virtual void speak();//也可以写成 virtual void speak() = 0; };
class Dog:public Animal{ public: void speak(){ cout << “狗在说话” << endl; }; };
class Cat:public Animal{ public: void speak(){ cout << “猫在说话” << endl; }; };
void speak(Animal& animal){ animal.speak(); }
int main() { Cat cat; Dog dog;
speak(cat);speak(dog);return 0;
}
<a name="iiAiK"></a>### 虚析构函数和纯虚析构函数**场景:**在多态使用时,如果子类有属性开辟到堆区,那么父类指针在释放时无法调用到子类的析构函数,如果子类没有堆区数据,是可以无写虚析函数的**解决方案:**将父类的析构函数改为虚析构或纯虚析构。<br />虚析构和纯虚析构的共性:- 可以解决父类指针释放子类对象- 都需要有具体的函数实现虚析构或纯虚析构的区别- 纯虚析构由于是抽象类,无法实例化。<a name="SO1sD"></a>#### 虚析构函数```c#include <iostream>#include <string>using namespace std;class Animal{public:virtual void speak();virtual ~Animal(){};//虚析构函数};class Dog:public Animal{string* name;public:Dog(string name):Animal(){this->name = new string(name);}void speak(){cout << "狗在说话" << endl;};~Dog(){if (name != NULL){delete name;}}};void speak(Animal& animal){animal.speak();}int main(){Dog dog("哈密瓜");speak(dog);return 0;}
纯虚析构函数
#include <iostream>#include <string>using namespace std;class Animal{public:virtual void speak();virtual ~Animal() = 0;//纯虚析构函数};Animal::~Animal(){}; //如果是纯虚析构函数,则这一行不能少,否则编译无法通过,因为如果少了这一行,编译器会认为基类没有了析构函数class Dog:public Animal{string* name;public:Dog(string name):Animal(){this->name = new string(name);}void speak(){cout << "狗在说话" << endl;};~Dog(){if (name != NULL){delete name;}}};void speak(Animal& animal){animal.speak();}int main(){Dog dog("哈密瓜");speak(dog);return 0;}
