将派生类的对象赋给基类指针,则可以使用该指针访问基类的数据和函数,但不能访问派生类的数据和函数。
#include<iostream>
#include<stdlib.h>
using namespace std;
class father
{
public:
father() :age(45){ cout << "调用father类的构造函数并初始化age为:" << age << endl; }
~father(){ cout << "调用father类的析构函数" << endl; }
void jump()const{ cout << "父亲可以跳五个台阶" << endl; }
virtual void run()const{ cout << "父亲可以跑万米" << endl; }
protected:
int age;
};
class son :public father
{
public:
son(){ cout << "调用son类的构造函数" << endl; }
~son(){ cout << "调用son类的析构函数" << endl; }
void math(){ cout << "儿子会数学" << endl; }
void jump()const{ cout << "儿子可以跳十个台阶" << endl; }
void run()const{ cout << "儿子可以跑十万米" << endl; }
};
void main()
{
son a;//首先调用父类的构造函数,然后在调用自己的构造函数;析构的时候顺序相反。
a.jump();//可以直接调用自己衍生出来的函数
a.math();
a.father::jump();//父类和子类中有相同函数名的函数时,若不加限定符默认的是调用子类中的函数,若想调用父类中的此函数,需要加限定符。
father*pfather = new son;//在堆中创建一个派生类的对象并把该派生类对象赋给基类指针,可通过指针直接访问父类中的函数。
pfather->jump();
pfather->run();//父类的run函数前面加了virtual,根据对象是谁,调用该对象的同名函数
(*pfather).run();//调用派生类的函数
father b;//定义一个父类的对象
b = *pfather;//将子类的对象赋值给父类的对象
b.run();//调用父类的函数
father &c=(*pfather);//定义一个父类的引用,作为一个子类对象的别名。
c.run();//调用的是派生类的函数
father*qfather = new father;
qfather->run();//
//pfather->math();//会报错,父类的指针无法访问派生类中的数据和成员
son*pson = new son;
pson->math();
delete pson;//首先调用儿子类的析构函数,然后调用父类的析构函数
delete pfather;析构函数不说明为虚函数,那么在删除此指针时只调用父类的析构函数,若将析构函数说明为虚函数,那么当指针被删除时,系统会根据对象运行时的类型调用正确的析构函数。
delete qfather;
system("pause");
}
注意:
如果基类中定义了虚函数,析构函数也应该说明为虚函数,这样对内存的回收更准确些。