虚析构函数
- 含有虚函数的类,应该将析构函数声明为虚函数(虚析构函数) 
  
- delete父类指针时,才会调用子类的析构函数,保证析构的完整性
#include <iostream>
using namespace std;
class Animal {
public:
  int m_age;
  virtual void speak() {
    cout << "Animal::speak()" << endl;
  }
  virtual void run() {
    cout << "Animal::run()" << endl;
  }
  virtual ~Animal() {
    cout << "~Animal()" << endl;
  }
};
class Cat : public Animal {
public:
  int m_life;
  Cat() :m_life(0) {}
  void speak() {
    cout << "Cat::speak()" << endl;
  }
  void run() {
    cout << "Cat::run()" << endl;
  }
  ~Cat() {
    cout << "~Cat()" << endl;
  }
};
int main() {
  Animal *cat1 = new Cat();
  cat1->speak();
  cat1->run();
  delete cat1;
  getchar();
  return 0;
}
纯虚函数
- 纯虚函数:没有函数体且初始化为0的虚函数,用来定义接口规范
- 抽象类(Abstract Class) 含有纯虚函数的类,不可以实例化(不可以创建对象) 
  
- 抽象类也可以包含非纯虚函数
- 如果父类是抽象类,子类没有完全实现纯虚函数,那么这个子类依然是抽象类
#include <iostream>
using namespace std;
// 类似于Java中接口、抽象类
// 类似于OC中的协议protocol
// Animal是个抽象类
class Animal {
public:
  virtual void speak() = 0;
  virtual void run() = 0;
};
class Cat : public Animal {
public:
  void run() {
  }
};
class WhiteCat : public Cat {
public:
  void speak() {
  }
  void run() {
  }
};
int main() {
  Cat *cat = new WhiteCat();
  getchar();
  return 0;
}
多继承
- C++允许一个类可以有多个父类(不建议使用,会增加程序设计复杂度)
#include <iostream>
using namespace std;
class Student {
public:
  int m_score;
  Student(int score = 0) :m_score(score) { }
  void study() {
    cout << "Student::study() - score = " << m_score << endl;
  }
  ~Student() {
    cout << "~Student" << endl;
  }
};
class Worker {
public:
  int m_salary;
  Worker(int salary = 0) :m_salary(salary) { }
  void work() {
    cout << "Worker::work() - salary = " << m_salary << endl;
  }
  ~Worker() {
    cout << "~Worker" << endl;
  }
};
class Undergraduate : public Student, public Worker {
public:
  int m_grade;
  Undergraduate(
    int score = 0, 
    int salary = 0, 
    int grade = 0) :Student(score), Worker(salary), m_grade(grade) {
  }
  void play() {
    cout << "Undergraduate::play() - grade = " << m_grade << endl;
  }
  ~Undergraduate() {
    cout << "~Undergraduate" << endl;
  }
};
int main() {
  {
    Undergraduate ug;
    ug.m_score = 100;
    ug.m_salary = 2000;
    ug.m_grade = 4;
    ug.study();
    ug.work();
    ug.play(); 
  }
  cout << sizeof(Undergraduate) << endl;
  getchar();
  return 0;
}
多继承体系下的构造函数调用
#include <iostream>
using namespace std;
class Student {
public:
  virtual void study() {
    cout << "Student::study()" << endl;
  }
};
class Worker {
public:
  virtual void work() {
    cout << "Worker::work()" << endl;
  }
};
class Undergraduate : public Student, public Worker {
public:
  void study() {
    cout << "Undergraduate::study()" << endl;
  }
  void work() {
    cout << "Undergraduate::work()" << endl;
  }
  void play() {
    cout << "Undergraduate::play()" << endl;
  }
};
int main() {
  /*Undergraduate ug;
  ug.study();
  ug.work();
  ug.play();*/
  Student *stu = new Undergraduate();
  stu->study();
  Worker *worker = new Undergraduate();
  worker->work();
  cout << sizeof(Undergraduate) << endl;
  getchar();
  return 0;
}
多继承-虚函数
- 如果子类继承的多个父类都有虚函数,那么子类对象就会产生对应的多张虚表
同名函数
#include <iostream>
using namespace std;
class Student {
public:
  int m_age;
};
class Worker {
public:
  int m_age;
};
class Undergraduate : public Student, public Worker {
public:
  int m_age;
};
int main() {
  Undergraduate ug;
  ug.m_age = 10;
  ug.Student::m_age = 20;
  ug.Worker::m_age = 30;
  ug.Undergraduate::m_age = 40;
  cout << sizeof(Undergraduate) << endl;
  getchar();
  return 0;
}
//class Student {
//public:
//  void eat() {
//    cout << "Student::eat()" << endl;
//  }
//};
//
//class Worker {
//public:
//  void eat() {
//    cout << "Worker::eat()" << endl;
//  }
//};
//
//class Undergraduate : public Student, public Worker {
//public:
//  void eat() {
//    cout << "Undergraduate::eat()" << endl;
//  }
//};
//
//int main() {
//  Undergraduate ug;
//  ug.eat();
//  ug.Worker::eat();
//  ug.Student::eat();
//  ug.Undergraduate::eat();
//
//  getchar();
//  return 0;
//}
菱形继承
- 菱形继承带来的问题 
 - 最底下子类从基类继承的成员变量冗余、重复
- 最底下子类无法访问基类的成员,有二义性
  
 
 
#include <iostream>
using namespace std;
// 非虚继承:(10 + 10 + 3) * 4 = 23 * 4
// 虚继承:(10 + 2 + 2 + 1) * 4 = 15 * 4
class Person {
public:
  int m_age;
  int m_age1;
  int m_age2;
  int m_age3;
  int m_age4;
  int m_age5;
  int m_age6;
  int m_age7;
  int m_age8;
  int m_age9;
};
class Student : virtual public Person {
public:
  int m_score;
};
class Worker : virtual public Person {
public:
  int m_salary;
};
class Undergraduate : public Student, public Worker {
public:
  int m_grade;
};
int main() {
  /*Undergraduate ug;
  ug.m_grade = 10;
  ug.m_score = 20;
  ug.m_salary = 20;*/
  cout << sizeof(Student) << endl;
  getchar();
  return 0;
}
虚继承
#include <iostream>
using namespace std;
// 多继承:增加程序的复杂度
// 多继承有一个很好的用途:
// 一个类实现多个接口(Java)
// 一个类遵守多份协议(OC)
// 一个类继承多个抽象类(C++)
class JobBaomu {
  virtual void clean() = 0;
  virtual void cook() = 0;
};
class JobTeacher {
  virtual void playBaseball() = 0;
  virtual void playFootball() = 0;
};
class SalesMan : public JobBaomu {
  void clean() {
  }
  void cook() {
  }
};
class Student : public JobBaomu, public JobTeacher {
  void clean() {
  }
  void cook() {
  }
  void playBaseball() {
  }
  void playFootball() {
  }
};
int main() {
  // 兼职中心
  // 招聘一些人来做兼职
  // 兼职的岗位很多种(保姆、老师、开挖掘机)
  // 应聘的人种类也很多(学生、XXX)
  getchar();
  return 0;
}