C++基类指针与派生成员

文章来源: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个字节。












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

私房菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值