实现基类(父类)以及派生类(子类),验证继承与转换--赋值兼容规则:
-
子类对象可以赋值给父类对象(切割/切片)
-
父类对象不能赋值给子类对象
-
父类的指针/引用可以指向子类对象
-
子类的指针/引用不能指向父类对象(可以通过强制类型转换完成)
- #include<iostream>
- using namespace std;
- class People //父类或者基类
- {
- public:
- void Display()
- {
- cout << "_name" << endl;
- }
- protected:
- string _name;
- };
- class Student:public People //子类或者派生类
- {
- protected:
- int _num;
- };
- void Test()
- {
- People p;
- Student s;
- p = s; //切片
- //s = p; //无法通过,说明父类对象不可以赋值给子类对象
- People* p1 = &s; //父类的指针和引用可以指向子类
- People& p2 = s;
- //Student* s1 = &p; //子类的指针和引用不可以指向父类
- //Student& s2 = p;
- Student* s1 = (Student*)&p; //可以通过强转实现
- Student& s2 = (Student&)p;
- //p2->_num = 10; //_num是子类对象,要越界父类对象才能访问到子类对象
- //s2._num = 20;
- }
- int main()
- {
- Test();
- system("pause");
- return 0;
- }
如何书写基类与派生类的默认成员函数呢?如:构造函数、拷贝构造函数、赋值运算符重载、析构函数。
- #include<iostream>
- using namespace std;
- class People
- {
- public:
- People(const char* name)
- :_name(name)
- {
- cout << "People()" << endl;
- }
- People(const People& p)
- :_name(p._name)
- {
- cout << "People(const People& p)" << endl;
- }
- People& operator=(const People& s)
- {
- if (&s != this)
- {
- cout << "People& operator= (const People& s)"<<endl;
- _name = s._name;
- }
- return *this;
- }
- ~People()
- {
- cout << "~People()" << endl;
- }
- protected:
- string _name;
- };
- class Student:public People
- {
- public:
- Student(const char* name, int num)
- :People(name)
- , _num(num)
- {
- cout << "Student()" << endl;
- }
- Student(const Student& s)
- :People(s)
- , _num(s._num)
- {
- cout << "Student(const Student& s)" << endl;
- }
- Student& operator= (const Student& s)
- {
- if (this != &s)
- {
- cout << "Student& opeartor= (const Student& s)" << endl;
- People::operator=(s);
- _num = s._num;
- }
- return *this;
- }
- ~Student()
- {
- cout << "~Student()" << endl;
- }
- protected:
- int _num;
- };
- void Test()
- {
- Student s1("张三",15);
- Student s2(s1);
- Student s3("李四",12);
- s3 = s1;
- }
- int main()
- {
- Test();
- system("pause");
- return 0;
- }
虚函数&多态
虚函数:
在类的成员函数前面加上virtual,成为虚函数。
虚函数的重写:
当在子类中定义了一个与父类相同的虚函数时,就称为子类的函数重写了父类的虚函数。
多态:
使用父类的函数或者指针调用函数时,若指向父类的虚函数就调用父类的虚函数,若调用子类的虚函数就调用子类的虚函数。
如:
- #include<iostream>
- using namespace std;
- class People
- {
- public:
- virtual void BuyTickets()
- {
- cout << "买票" << endl;
- }
- };
- class Student :public People
- {
- public:
- virtual void BuyTickets()
- {
- cout << "买票-半价" << endl;
- }
- };
- void Fun(People& p)
- {
- p.BuyTickets();
- }
- void Test()
- {
- People p;
- Student s;
- Fun(p);//People为父类,则调用父类的虚函数。
- Fun(s);//调用子类的虚函数。
- }
- int main()
- {
- Test();
- system("pause");
- return 0;
- }
expand:C++多态总结:多态原理、虚函数指针、重载重写 ,赋值兼容性原则
http://blog.sina.com.cn/s/blog_4b9eab320102varo.html
目录
- 问题引出赋值兼容性遇上函数重写
- 面向对象新需求
- C提供的多态解决方案
- 重载重写重定义
- 多态的实现原理以及多态的理解
- 多态原理研究证明VPTR指针的存在
- 虚函数表指针VPTR被编译器初始化的过程
- 为什么要定义虚析构函数
- 基类和子类对象指针混搭风