基本应用

  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4. class People{
  5. private:int age;
  6. private:string name;
  7. public:People(string name,int age){
  8. this->name = name;
  9. this->age = age; //this是一个指针,指向当前的对象
  10. }
  11. public: void println(){
  12. cout << "姓名为" << name << ",年纪为:" << age << endl;
  13. }
  14. };
  15. class Student:public People{//设置继承方式为public
  16. public:Student(string name,int age):People(name,age){
  17. //继承父类的构造函数
  18. }
  19. };
  20. int main()
  21. {
  22. Student stu("小明",12);
  23. stu.println();
  24. return 0;
  25. }

继承方式

  • 公共继承
  • 保护继承
  • 私有继承

  • 公共继承 ```cpp class People{ };

class Student:public People{ //保留父类所有成员的访问权限 };

  1. - 保护继承
  2. ```cpp
  3. class People{
  4. };
  5. class Student:protected People{
  6. //保留父类protected及private的成员的访问权限
  7. //将父类所有public的成员修改为protected
  8. };
  • 私有继承 ```cpp class People{ };

class Student:private People{ //所有父类的成员都修改为private };

  1. <a name="q53GX"></a>
  2. ###
  3. <a name="eVEOa"></a>
  4. ### 访问与父类同名的变量及方法
  5. ```java
  6. #include <iostream>
  7. #include <string>
  8. using namespace std;
  9. class People{
  10. public:void say(){
  11. cout << "People say" << endl;
  12. }
  13. public:static void go(){
  14. cout << "People go" << endl;
  15. }
  16. };
  17. class Student:public People{
  18. public:void say(){
  19. cout << "Student say" << endl;
  20. }
  21. public:static void go(){
  22. cout << "Student go" << endl;
  23. }
  24. };
  25. int main()
  26. {
  27. Student stu;
  28. stu.say();//调用Student中的成员函数say
  29. stu.People::say();//访问父类中的成员函数say
  30. Student::go();//调用Student中的静态函数go
  31. Student::People::go();//访问父类中的静态函数go
  32. return 0;
  33. }

Student say People say Student go People go

一个类继承多个类

  1. class People{
  2. };
  3. class Animal{
  4. };
  5. class Student:public People,public Animal{
  6. };

注:C++开发中不建议用多继承

多态及虚函数

多态的概念和Java是一样的,即允许父类和子类进行类型转换

  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4. class Animal{
  5. public:
  6. //virtual为声明speak为虚函数
  7. virtual void speak(){
  8. cout << "动物在说话" << endl;
  9. };
  10. };
  11. class Dog:public Animal{
  12. public:
  13. void speak(){
  14. cout << "狗在说话" << endl;
  15. };
  16. };
  17. class Cat:public Animal{
  18. public:
  19. void speak(){
  20. cout << "猫在说话" << endl;
  21. };
  22. };
  23. void doSpeak(Animal& animal){
  24. animal.speak();
  25. }
  26. int main()
  27. {
  28. Cat cat;
  29. Dog dog;
  30. doSpeak(cat);
  31. doSpeak(dog);
  32. return 0;
  33. }

注:

  • 如果不声明speak是虚函数(virtual),则执行doSpeak时,无论传参是Cat还是Dog,输出结果都会是Animal中的“动物在说话”
  • 但在声明speak是虚函数以后,就会发现,在这种场景下,实际上父类的speak函数的实现是没有意义,那么这种场景下,可以把父类的speak修改为纯虚函数,即抽象函数。

纯虚函数及抽象类

如果一个类中有个纯虚函数,这个类就叫抽象类,其概念和特点其实和Java是一样的

  • 无法实例化抽象类
  • 子类必须重写抽象类中的纯虚函数,否则也属于抽象类 ```c

    include

    include

    using namespace std;

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;

  1. speak(cat);
  2. speak(dog);
  3. return 0;

}

  1. <a name="iiAiK"></a>
  2. ### 虚析构函数和纯虚析构函数
  3. **场景:**在多态使用时,如果子类有属性开辟到堆区,那么父类指针在释放时无法调用到子类的析构函数,如果子类没有堆区数据,是可以无写虚析函数的
  4. **解决方案:**将父类的析构函数改为虚析构或纯虚析构。<br />虚析构和纯虚析构的共性:
  5. - 可以解决父类指针释放子类对象
  6. - 都需要有具体的函数实现
  7. 虚析构或纯虚析构的区别
  8. - 纯虚析构由于是抽象类,无法实例化。
  9. <a name="SO1sD"></a>
  10. #### 虚析构函数
  11. ```c
  12. #include <iostream>
  13. #include <string>
  14. using namespace std;
  15. class Animal{
  16. public:
  17. virtual void speak();
  18. virtual ~Animal(){};//虚析构函数
  19. };
  20. class Dog:public Animal{
  21. string* name;
  22. public:
  23. Dog(string name):Animal()
  24. {
  25. this->name = new string(name);
  26. }
  27. void speak(){
  28. cout << "狗在说话" << endl;
  29. };
  30. ~Dog(){
  31. if (name != NULL)
  32. {
  33. delete name;
  34. }
  35. }
  36. };
  37. void speak(Animal& animal){
  38. animal.speak();
  39. }
  40. int main()
  41. {
  42. Dog dog("哈密瓜");
  43. speak(dog);
  44. return 0;
  45. }

纯虚析构函数

  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4. class Animal{
  5. public:
  6. virtual void speak();
  7. virtual ~Animal() = 0;//纯虚析构函数
  8. };
  9. Animal::~Animal(){}; //如果是纯虚析构函数,则这一行不能少,否则编译无法通过,因为如果少了这一行,编译器会认为基类没有了析构函数
  10. class Dog:public Animal{
  11. string* name;
  12. public:
  13. Dog(string name):Animal()
  14. {
  15. this->name = new string(name);
  16. }
  17. void speak(){
  18. cout << "狗在说话" << endl;
  19. };
  20. ~Dog(){
  21. if (name != NULL)
  22. {
  23. delete name;
  24. }
  25. }
  26. };
  27. void speak(Animal& animal){
  28. animal.speak();
  29. }
  30. int main()
  31. {
  32. Dog dog("哈密瓜");
  33. speak(dog);
  34. return 0;
  35. }