今天把多态这章看完了,前几天学了一点动态规划的内容,等学懂之后自己再回顾回顾。
引入
基类(people)和 子类(chinese、japan、american、english)都有成员函数-say
class people{
void say()const{
cout << " " << endl;
}
};
class chinese{
void say() const{
cout << "你好" << endl;
}
};
class american{
void say() const{
cout << "hello" << endl;
}
};
代码重用的话使用继承的话比较安全,不用复制代码,造成不必要的错误。
继承之后,基类中有的成员函数,子类就可以使用了,但是子类也可以重新定义,很多子类的话,那么基类中的某些成员函数在子类中就有多种含义了。
比如上面的say函数,静态的多态性就是chinese.say() 和 american.say()结果不同
对于基类和子类之间
1、基类指针访问基类对象——正常
2、子类指针访问子类对象——正常
3、基类指针访问子类对象——可以,因为子类也是一个基类,当然只能访问子类中属于基类的那部分。
4、子类指针访问基类对象——错误
既然3是允许的,那么当把子类对象的地址赋给基类指针的时候,通过基类指针访问的成员函数say的时候,结果是基类的say
这应该是设计的默认结果,默认由指针或者引用类型(句柄类型)决定调用基类还是子类的函数,当然了3可行,4不可行,那么默认的就是调用基类中的say函数
要想改变这种情况呢,就把基类中的say函数之前加上virtual,那么则由句柄指向的对象类型来决定到底哪一个函数被调用。
只有3情况需要virtual,也就是说声明了virtual函数之后,把子类地址传给基类指针,那么就可以通过基类只针对调用子类的函数了。
所以
函数不声明virtual,那么基类指针访问子类对象就还是调用基类函数了。函数声明virtual后,那么基类指针访问子类对象就是调用子类的函数了。
这样才能达到基类指针多态性操作子类对象的目的
虚函数是virtual void say() const{----}
纯虚函数就是virtual void say() const = 0;
纯虚函数不提供任何函数实现,每个子类必须重载,
纯虚函数之所以出现就是基类实现这个函数没有意义或者没法实现,但是子类都有必要使用该函数。
它就是为了抽象化了,可能就是提供一个接口,然后利用抽象基类声明指针和引用。
利用这种指针和引用可以多态性的操作子类的对象。
等到有机会再补充。
从明天开始略微实战一下,写一个俄罗斯方块,估计要一周。