isA
子类的对象可以赋值给父类:
子类给父类赋值时,只能赋值父类有的数据成员和函数,而无法接受其他的数据
指向父类的指针可以指向子类:
父类只能指向自己有的数据成员和函数,无法指向自己没有的
- 演示:
- 对象作为参数使用
演示代码:
//test1(),test2()
不会产生临时的变量,test1 (Person p)
传入一个对象,p是一个临时对象,调用完成之后会被销毁,test1()
结束后会执行析构函数
test2 (Person &p)
//使用基类的引用可以接受基类的对象以及派生类的对象
#include <iostream>
#include "Person.h"
#include "Soldier.h"
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
test1 (Person p){
p.play();
}
test2 (Person &p){//使用基类的引用可以接受基类的对象以及派生类的对象
p.play();
}
test3 (Person *p){
p->play();
}
int main(int argc, char** argv) {
Person p;
Soldier s;
cout << endl;
test1(p);
test1(s);
cout << endl;
test2(p);
test2(s);
cout << endl;
test3(&p);//test3(Person *p)参数是一个基类的指针,放地址
test3(&s);
cout << endl;
return 0;
}
演示结果:
-
子类内存释放问题
//
Person *p = new Soldier
;//父类的指针指向子类,只能指向自己有的成员或者函数
//p->play();
如图,先执行父类的构造函数,再执行子类的构造函数 ,析构函数最后只执行~Person()
子类的析构函数不执行,可能导致子类的内存泄漏。
当存在继承关系时,用父类的指证指向子类时,并用父类的指针释放这块内存时,子类的构造函数不执行,解决此类问题时 ,用虚函数virtual可解决此类问题
virtual ~Person();
virtual ~Soldier();
演示代码:
- main文件
#include <iostream>
#include "Person.h"
#include "Soldier.h"
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int main(int argc, char** argv) {
//Soldier soldier;
/*//Person p = soldier;//soldier初始化p,p是指向父类的一个指针
Person p;
p = soldier; //直接赋值给p
p.play();//play中打印的是jim,子类中的m_strName 都赋值给父类对象中的成员
*/
//Person *p = &soldier;
//p->play();//指针的方式验证
// Person的对象只能调用自己有的函数及成员,如p->work()则不能调用
Person *p = new Soldier;//父类的指针指向子类,只能指向自己有的成员或者函数
p->play();
delete p;
p = NULL;
return 0;
}
- Person文件
#include <string>
using namespace std;
class Person
{
public:
Person(string name = "jiyacheng");
virtual ~Person();
void play();
protected:
string m_strName;
};
Person:: Person(string name){
m_strName = name;
cout << "Person()" << endl;
}
Person:: ~Person(){
cout << "~Person()" << endl;
}
void Person:: play(){
cout << "play()" << endl;
cout << m_strName << endl;
}
- Soldier文件
#include "Person.h"
#include <string>
using namespace std;
class Soldier: public Person
{
public:
Soldier(string name = "jim",int age = 10);
virtual ~Soldier();
void work();
protected:
int m_iAge;
};
Soldier:: Soldier(string name,int age){
m_strName = name;
m_iAge = age;
cout << "Soldier()" << endl;
}
Soldier:: ~Soldier(){
cout << "~Soldier()" << endl;
}
void Soldier:: work(){
cout << "work()" << endl;
cout << m_strName << endl;
}