重载、隐藏
class Base
{
public:
Base(int data = 10) :ma(data) {}
void show() { cout << "Base::show()" << endl; }//#1
void show(int) { cout << "Base::show(int)" << endl; }//#2
protected:
int ma;
};
class Derive : public Base
{
public:
Derive(int data = 20) :Base(data), mb(data) {}
private:
int mb;
};
派生类都会去调用从基类继承而来的相应的不带参数的和带整型参数的show方法
那么接下来,我们在派生类中也自定义一个show方法
class Base
{
public:
Base(int data = 10) :ma(data) {}
void show() { cout << "Base::show()" << endl; }//#1
void show(int) { cout << "Base::show(int)" << endl; }//#2
protected:
int ma;
};
class Derive : public Base
{
public:
Derive(int data = 20) :Base(data), mb(data) {}
void show() { cout << "Derive::show()" << endl; }//#3
private:
int mb;
};
派生对象调用show方法,肯定是优先调用自己的show方法了,优先在自己的作用域下去找相应的成员名字,派生类中没有相应的成员的名字,才从基类继承而来的成员方法去找。
当派生对象调用int类型的show方法时,发现派生类中没有对应的带int参数的show方法,它找到从基类继承而来的带int类型的参数的方法,但是它不可以调用。
编译器报错了。
根据提示可以看出来,它还是想调用派生类中的不带参数的show方法。它为什么不调用从基类继承而来的带int参数的成员方法呢???
基类和派生类中的成员方法或者成员变量的名字可以相同,因为作用域不同。名字相同的成员就要产生关系了。
重载关系
一组函数要重载,必须处在同一个作用域当中;而且函数名字相同,参数列表不同
所以Base类里面的2个show方法是属于重载关系。
但是下面图中的这2个show方法不能说是重载关系
因为这两个show方法的作用域是不同的。
隐藏(作用域的隐藏)的关系
在继承结构当中,派生类的同名成员,把基类的同名成员给隐藏调用了
图中的第1个和第3个show方法就是属于隐藏关系
图中的第2个和第3个show方法也是属于隐藏关系
如果派生对象想调用基类的同名方法
派生对象调用下面这个show方法,也是隐藏基类的同名方法了,一定调用的是自己的show方法,所以报错了。
如果一定要调用,就这么做:
基类和派生类之间的转换调用规则
把继承结构,也说成从上(基类)到下(派生类)的结构
派生类对象赋值给基类对象可不可以?
一般来说,基类小,派生类大。
把下面的赋值到上面去,可以吗?
可以的。因为基类对象只需要前面那一段而已,就是把派生对象的基类部分赋给基类对象。
基类一般代表人类,派生类代表学生。现在需要一个人,给你一个学生,是可以的。
这是类型从下到上的转换,是可以的。
基类对象赋给派生类对象可不可以?
不可以。
现在人家需要学生来解高等数学微积分,现在从街道上随便拉一个人来,肯定不行啊,他不一定会解微积分啊
基类对象最多把派生类对象的基类部分给赋值了,派生类对象的自己那部分咋办???凉拌,计算机是死的,你不告诉它,它没办法去做。
类型从上到下的转换,是不允许的
基类指针(引用)可以指向 派生类对象吗?
可以的。
派生类对象本身就有2部分组成:一个是从基类继承来的成员,一个是派生类自己定义的成员。
基类指针可以指向派生类对象,但是只能访问派生类对象的的基类的成员,不能访问派生类特有的成员,因为指针的类型限制了指针解引用的能力
类型从下到上的转换,是OK的
此时,派生类对象的show是无论如何都访问不了的
除非做类型的强转
编译的时候就去派生类对象的自己的作用域中寻找方法
派生类指针(引用)可以指向基类对象吗?
基类对象的内存只有这么大。
但是当派生类的指针一解引用,它访问的内存会比基类的内存大,但是基类对象只有基类的那部分才是合法的,如果派生类指针访问基类对象的“派生类部分”,就会造成内存的非法访问
指针的类型决定了指针的能力太强了,一解引用访问的空间的肯定大于基类对象的内存空间,后面那些空间还没分配给应用呢
类型从上到下的转换,是不可以的。
总结:在继承结构中进行上下的类型转换,默认只支持从下到上的类型的转换 OK
把基类对象强制成派生类类型,这样是非常危险的,
这里面访问的是谁的show方法啊???
访问的是派生类的show方法,但是实际上,内存中是没有派生类对象的。
我们在这里只是调用派生类的show,只是进行了打印而已,但是如果在这个show方法里面有对派生类成员变量的访问,就肯定有问题了。