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个字节。












阅读全文
0 0
原创粉丝点击