C++基类指针与派生成员
来源:互联网 发布:如何使用广电网络电视 编辑:程序博客网 时间:2024/05/14 03:57
文章来源:http://blog.csdn.net/shift_wwx/article/details/78604016
本文是自己在学习了继承和派生,以及C++的多态性之后通过实例来说明继承和派生的过程,请大家不吝赐教。
1、继承的方式
继承方式有三种:public、private、protected。
具体的不做介绍,网上有很多文章。
注意的是,基类中的private成员是无法继承使用的,只能基类自己使用。protected成员也只能提供给派生类或者自己使用,对象是无法使用的。
2、多态方式
方式分两种:静态多态和动态多态。
静态多态指的是函数的重载和运算符的重载;
动态多态指的是虚函数。
虚函数的提出也就是为了多态性,而多态也是针对于基类指针或者基类的引用。对于实例对象而言就不存在这样的情况,直接引用即可。
3、实例
上面简单说明了下继承和派生,以及多态的产生,下面通过实例来确认下这些过程。
基类和派生类的code如下:
class Base {public:Base() : value(1) {}~Base() {}void print() {cout << "This is Base class..." << endl;cout << "value is " << value << endl;}int value;};class FromBase : public Base {public:FromBase() : value(2) {}~FromBase() {}void print() {cout << "This is FromBase class..." << endl;cout << "value is " << value << endl;}int value;};
为了区分value的从属,在构造的时候分别对两个类中的value进行了初始化。
用来测试的code如下:
class Test1{public:Test1();~Test1();void test();};Test1::Test1() {cout << "class Test1" << endl;}Test1::~Test1() {cout << "class Test1 destructor..." << endl;}void Test1::test() {Base base;FromBase fbase;Base *p = NULL;cout << "base's address is: " << &base << endl;cout << "fbase's address is: " << &fbase << endl;cout << "point p's address is: " << p << endl;p = &base;cout << "point p's address is: " << p << endl;p->print();cout << "point value's address is: " << &(p->value)<< ", member value's address is: " << &base.value<< ", value is "<< p->value << endl;p = &fbase;cout << "point p's address is: " << p << endl;p->print();cout << "point value's address is: " << &(p->value)<< ", member value's address is: " << &fbase.value<< ", value is " << p->value << endl;}运行结果如下:
通过结果可以看出:
- 两个对象创建成功,都能分配到内存;
- 通过基类指针调用的两个类中的成员函数print()其实都是基类的print()函数;
- 通过基类指针调用的两个类中的成员变量value其实都是基类的value;
对于多态性的认识和了解,我们将基类中的print()改成virtual属性,Base类改动后如下:
class Base {public:Base() : value(1) {}~Base() {}virtual void print() {cout << "This is Base class..." << endl;cout << "value is " << value << endl;}int value;};运行结果如下:
我们发现多态性真的生效了(完全废话,那必须生效)。可是value的值怎么办呢?多态性中没有成员变量的多态吧?
从log中可以看出:
Base中通过指针指向的value的地址和通过Base对象引用的value的地址是一样的,这一点也是毋庸置疑的。
FromBase中通过指针指向的value的地址和通过对象引用的value的地址并不一样,从这里我们可以知道派生类的内存大概分配方式。
总结:
通过基类指针可以通过virtual函数实现访问派生类的函数。
通过基类指针是无法访问派生类的成员变量。
基类的析构函数最好加个virtual,如果是指针delete的时候,会只会调用基类的析构,那如果派生类中有个成员指针,new之后需要在析构中delete,就没办法实现,最后出现OOM。
在对象的首地址和value地址中间隔了4个字节的空间,这个应该是放虚函数表指针的地方,对于32位系统应该是4个字节。
- C++基类指针与派生成员
- 指向基类/派生类指针,指向基类成员/派生类成员指针,及互相赋值
- 指向基类/派生类指针,指向基类成员/派生类成员指针,及互相赋值
- !!!!!!!!!!!!!!!!C++:派生类中重定义基类的成员函数与虚函数区别在哪里?
- 基类指针与派生类指针的相互转换
- 基类指针、派生类指针与他们的关系
- 基类指针、派生类指针与他们的关系
- (转)基类指针与派生类指针
- 基类指针与派生类指针的相互转换
- 基类指针与派生类指针的相互转换
- 基类指针与派生类指针的相互转换
- 派生类与派生类对象对基类成员的访问
- 继承与派生4:派生类中对基类成员的重定义
- 继承与派生:派生类对基类成员的访问控制之公有继承
- 三十七、继承与派生:派生类对基类成员的访问控制之公有继承
- 派生类成员的标识与访问
- YTU-OJ-Problem J: B3 指向基类的指针访问派生类的成员函数
- OJ——指向基类的指针访问派生类的成员函数
- 【java基础:net】基于TCP的客户端与服务端进行字母大小写转换的Demonstration
- Android ShapeButton
- 【MyBatis】mybatis快速入门(二)
- Sklearn-RandomForest随机森林参数及实例
- EAST: An Efficient and Accurate Scene Text Detector安装
- C++基类指针与派生成员
- Nexpose部署教程
- MiniUI的多表整合crud
- [bzoj1005]:[HNOI2008]明明的烦恼(prufer序列+质因数分解+高精乘)
- Solr:schema版本号区别(引发IK分词错误)
- 基于朴素贝叶斯的文本分类
- 线程并发六:线程池--Executor框架
- JS 字符串方法集合
- K-means聚类算法-机器学习ML