C++面向对象的继承特性:父类和子类的类型兼容规则
1.何为类型兼容规则
类型兼容规则是父类和子类在数据类型方面的兼容规则。C
和C++
都是强类型语言,任何变量和对象、指针、引用等都有它自己的类型,编译器根据类型来确定很多事的。除了类型要匹配,还需要兼容。比如int
和short
、char
就是兼容的,它们对内存里二进制数据的解读方式是一样的,而int
和float
,尽管它们都是占4个字节,但是它们对于内存中二进制数据的解读方式是完全不一样的,所以它们完全不兼容。
派生类是基类的超集,基类(除了构造析构函数)有的派生类都有,派生类有的基类则不一定有,所以这2个类型间有关联。派生类和基类是兼容的,这体现在派生类对象可以cast
(裁剪)后当作基类对象(把派生类多出来的裁剪掉,将基类中的保存下来),而基类对象不能放大成派生类对象,否则就可能会出错(访问基类有的没问题,但是访问派生类特有的就会出问题)。
考虑到指针和引用与对象指向后,派生类和基类对象的访问规则就是所谓类型兼容规则。
2.类型兼容规则的常见情况
先定义好2个类:
#include<iostream>
using namespace std;
class person
{
public:
string name;
int age;
person(string Name,int Age):name(Name),age(Age){
};
void info(void)
{
cout<<"person info()."<<endl;
}
};
class man:public person
{
public:
bool male;
man(string Name,int Age,bool Male):person(Name,Age),male(Male){
};
void info(void)
{
cout<<"man info()."<<endl;
}
};
类型兼容规则①:子类对象可以当作父类对象使用,也就是说子类对象可以无条件隐式类型转换为一个父类对象。
int main(int argc,char**argv)
{
man tom;
person* p =&tom; //类型兼容,所以编译运行都没有报错
p->info();
return 0;
}
输出:
person info().
执行的是person
的info()
,而不是man
的,说明这里真的把tom
当作person
类来使用了。
类型兼容规则②:子类对象可以直接初始化或直接赋值给父类对象。
int main(int argc,char**argv)
{
man tom("tom",15,1);
person p = tom;
cout<< p.name<<" "<<p.age<<endl;
return 0;
}
输出:
扫描二维码关注公众号,回复:
12680066 查看本文章

tom 15
类型兼容规则③:父类指针可以直接指向子类对象,反过来则会编译报错。
int main(int argc,char**argv)
{
person jack;
man tom;
person* p =&tom; //类型兼容,所以编译运行都没有报错
man* q =&jack; //编译报错不通过
return 0;
}
类型兼容规则④:父类引用可以直接引用子类对象,反过来则不可以。
int main(int argc,char**argv)
{
man tom;
person& p =tom;
p.info();
return 0;
}
输出:
person info().
执行的同样是person
的info()
。
3.总结
派生类对象可以作为基类的对象使用,但是只能使用从基类继承的成员。类型兼容规则是多态性的重要基础之一,子类就是特殊的父类 (base *p = &child;
)。