【C++】关于继承、多态的重点部分复习
来源:互联网 发布:ubuntu安装mysql.gz 编辑:程序博客网 时间:2024/05/21 06:21
关于继承和多态之前的博客中有讲到,但因为最近在复习C++的一些概念,所以把一些遗漏的同样是重点的知识点再简单整理一下,具体基础知识请戳链接:
继承:http://blog.csdn.net/chaseraod/article/details/69704143
多态:http://blog.csdn.net/chaseraod/article/details/69704143
1,C++的三大特性是什么?分别说说你的理解。
封装、继承、多态。
(1)封装:封装是C++面向对象的一大特性。是指隐藏对象的具体属性和实现方式,只对外界暴露公共接口。封装的好处:.将变化隔离;2.便于使用。4.提高安全性。
(2)继承:父类原有的特性在加上某种限制(public、protected、private)后,子类同样具有其特性,并且可以加上自己独有的特性,继承实现了复用性,在现实中的应用广泛。
(3)多态:多态是通过virtual关键字实现虚函数的重写,以及父类指针或引用实现动态绑定。
2,如何让一个类不能被继承?
这道题考查队继承的理解,子类的初始化一定会去调用父类的构造函数,因此当我们把父类的构造函数设为私有时,这个类就不能被继承。
代码:
class AA{ private: AA() {} protected: int _a; }class BB:public AA{ public: BB() {} private: int _b;
3,什么情况下必须把父类的析构函数设为私有,如果不设为私有,会有什么危害?
我们先来看以下代码:
class A{public: ~A() { cout << "~A()" << endl; }};class B :public A{public: ~B() { cout << "~B()" << endl; }};int main(){ A *p = new B; delete p; system("pause"); return 0;}
运行结果:
可以看到,程序运行后并没有调用子类的析构函数,如果在子类的析构函数中有其他的工作,那么造成的损失将会很大。这里了是因为析构函数不够成多态,所以在动态联编时只会调用父类的析构函数。所以,通常我们将父类的析构函数设为虚函数,这样防止内存泄漏的损失。
4,C++类的成员函数中重载、重写(覆盖)、重定义(隐藏)分别是什么?
重载:(1)在同一作用域
(2)函数名相同、参数不同
(3)返回值可以不同
重写:(1)不在同一作用域(分别在基类和派生类)
(2)函数名相同、参数相同、返回值相同(协变除外)
(3)基类函数必须有virtual关键字
(4)访问修饰符可以不同
重定义:(1)在不同作用域中
(2)函数名相同
(3)在基类和派生类中只要不构成重写就是重定义
5,虚继承和多态中虚函数的区别
(1)虚继承
相信很多初学者都会分不清虚继承中的virtual和多态中的virtual,很多情况下会将他们搞混,但是它们之间并没有一点联系。
我们来看下面的代码:
class A{public: int _a;};class B :public A{public: int _b;};class C :public A{public: int _c;};class D :public B, public C{public: int _d;};int main(){ D d; d._a = 1; d._b = 2; d._c = 3; d._d = 4; system("pause\n"); return 0;}
上面的程序就是菱形继承:
程序一运行,会报这样的错
A类和B类中都有_a,就是菱形继承产生的二义性问题。虚继承就是解决菱形继承的二义性和数据冗余问题的。
class A{public: int _a;};class B :virtual public A{public: int _b;};class C :virtual public A{public: int _c;};class D :public B, public C{public: int _d;};int main(){ D d; d._a = 1; d._b = 2; d._c = 3; d._d = 4; system("pause\n"); return 0;}
此时编译通过,程序中_a只有一份。
那么,类A、B、C、D的大小各是多少呢?
为什么B和C的大小会是12字节呢?
通过上述的调试过程我们也可以看到,B中有成员_a,_b . C中有成员_a,_c,本应该是8字节,却多出了四个字节。
因为它们都是虚继承,内存中实际上有一个虚基表用来保存每个成员的相对偏移量,虚基类成员必须放在对象的最底层。所以,多出的四个字节实际是指向这个虚基表的指针。
(2)多态中的虚函数
class AA{public: AA() {} virtual ~AA() {} virtual void Print() { cout << "I am AA" << endl; }private: int _a;};class BB:public AA{public: BB() {} ~BB() {} void Print() { cout << "I am BB" << endl; }private: int _b;};int main(){ AA *p = new AA; AA *p1 = new BB; p->Print(); p1->Print(); system("pause"); return 0;}
运行结果:
这里的virtual是为了实现动态联编以实现多态。那么,类A,B的大小又是多少呢?
这里多出的四个字节和上面的一样吗?不一样!!!
多态中有一个虚表,但这里的虚表不同于虚继承中的虚基表,这里的虚表指的是虚函数表,一个类中有虚函数,则这个类的所有对象都含有一个指向虚表的指针,且所有的虚表指针指向同一个虚表,因此多出的四个字节便是这虚表指针的大小。
- 【C++】关于继承、多态的重点部分复习
- 关于封装、继承和多态的复习
- 关于C的复习
- C++ 封装 继承 多态 (重点多态的实现)
- 关于Java继承的一些复习
- 复习一:C的OOP-基本继承
- 复习二:C的OOP-Interface继承
- 复习四:C的OOP-多层继承
- 关于C语言中继承和多态的实现
- 关于C语言中继承和多态的实现
- 关于C语言中继承和多态的实现
- 复习继承和多态
- C语言与数据结构复习重点
- C语言重点知识复习1
- C语言重点知识复习2
- java复习2 封装、继承、多态的理解
- unity之继承的复习和多态的复习还有抽象类
- 不可思议的C++,关于继承
- javascript 获取滚动条高度+常用js页面宽度与高度
- HDOJ 1285 确定比赛名次 (拓扑排序)
- 博客的第一篇
- 475. Heaters
- 关于软件开发,你老板不知道的7件事
- 【C++】关于继承、多态的重点部分复习
- 优秀的软件开发人员必备超便利的工具
- 切题随想
- HTML_day02_form
- 恋爱与学习
- __stdcall、__cdcel和__fastcall三者的区别
- python 的__future__ 使用
- LeetCode 86. Partition List
- Simple Library Management System