关于基类和派生类之间的指针混合的思考
来源:互联网 发布:中国自主软件 编辑:程序博客网 时间:2024/06/10 16:44
基类类型的指针可以指向派生类的对象,但是派生类类型的指针不能指向基类的对象。
或者说一个基类对象的地址不能用来初始化一个派生类类型的指针。
如下:
class B
{
};
class D:public B
{
};
.........
B ob;
D od;
B * pB=&od;
D * pD=&ob; // error !
更一般的思考,基类代表着最少的确定的信息,而派生类则代表着较多的确定的信息。
一个基类的指针可以指向一个派生类的对象,意味着一个指针可以指向一个容纳了多于自己期望的信息量的对象。那么当这样的一个操作发生后,这个指针就可以做出一些额外的操作,这些操作是它在被定义的时候并没有期望能够做到的,或者说并没有想到的。
与此相对的是,一个派生类的指针则不能指向一个基类的对象。因为如果可以这样做的话,那么这个派生类的指针在被定义的时候所期望能做的所有事情中将有一部分不再能够做到,因为在它指向的那个基类的对象中根本就没有提供那些在派生类派生的时候新增加的方法。但是C++则保证一个指针定义之后,它至少要能够做和它被期望做的一样多的事情。那么,派生类指针指向基类对象的意图当然不能被允许。
看看下面的这个例子:
#include
#include
using namespace std;
class B
{
public:
inline void print(){ cout<<"class B print\n";}
};
class D:public B
{
public:
inline void print(){ cout<<"class D print\n";}
};
void foo(B *pb)
{
pb->print();
}
int main(int argc ,char argv[])
{
B ob;
D od;
B *pB1=&ob;
B *pB2=&od;
foo(pB1);
foo(pB2);
return 0;
}
程序的输出应该是:
class B print
class B print //为什么这里不是 class D print 呢?
D中的print和B中的print是什么关系呢?
************************************************************
下面做一个变形,有意让类之间发生 隐藏 而不是 覆盖。
class B
{
public:
void print() { cout<<" B class"<<endl; } //这里没有了virtual,将发生 隐藏。
};
class D:public B
{
public:
void print() { cout<<" D class"<<endl; } //隐藏B中的print,是 隐藏。
};
然后这样使用:
D dd;
B* Bp=ⅆ
D* Dp=ⅆ
Bp->print();
Dp->print();
// 使用方式和上面完全一样
输出结果为:
B class
D class
这里B中的print出现了(输出 B class),也就是说,在发生隐藏后,如果你强迫D(派生类)的对象去按照B(基类)的方式来表现,那么被B中被隐藏的那个函数将被实际调用。
或者说一个基类对象的地址不能用来初始化一个派生类类型的指针。
如下:
class B
{
};
class D:public B
{
};
.........
B ob;
D od;
B * pB=&od;
D * pD=&ob; // error !
更一般的思考,基类代表着最少的确定的信息,而派生类则代表着较多的确定的信息。
一个基类的指针可以指向一个派生类的对象,意味着一个指针可以指向一个容纳了多于自己期望的信息量的对象。那么当这样的一个操作发生后,这个指针就可以做出一些额外的操作,这些操作是它在被定义的时候并没有期望能够做到的,或者说并没有想到的。
与此相对的是,一个派生类的指针则不能指向一个基类的对象。因为如果可以这样做的话,那么这个派生类的指针在被定义的时候所期望能做的所有事情中将有一部分不再能够做到,因为在它指向的那个基类的对象中根本就没有提供那些在派生类派生的时候新增加的方法。但是C++则保证一个指针定义之后,它至少要能够做和它被期望做的一样多的事情。那么,派生类指针指向基类对象的意图当然不能被允许。
看看下面的这个例子:
#include
#include
using namespace std;
class B
{
public:
inline void print(){ cout<<"class B print\n";}
};
class D:public B
{
public:
inline void print(){ cout<<"class D print\n";}
};
void foo(B *pb)
{
pb->print();
}
int main(int argc ,char argv[])
{
B ob;
D od;
B *pB1=&ob;
B *pB2=&od;
foo(pB1);
foo(pB2);
return 0;
}
程序的输出应该是:
class B print
class B print //为什么这里不是 class D print 呢?
D中的print和B中的print是什么关系呢?
************************************************************
下面做一个变形,有意让类之间发生 隐藏 而不是 覆盖。
class B
{
public:
void print() { cout<<" B class"<<endl; } //这里没有了virtual,将发生 隐藏。
};
class D:public B
{
public:
void print() { cout<<" D class"<<endl; } //隐藏B中的print,是 隐藏。
};
然后这样使用:
D dd;
B* Bp=ⅆ
D* Dp=ⅆ
Bp->print();
Dp->print();
// 使用方式和上面完全一样
输出结果为:
B class
D class
这里B中的print出现了(输出 B class),也就是说,在发生隐藏后,如果你强迫D(派生类)的对象去按照B(基类)的方式来表现,那么被B中被隐藏的那个函数将被实际调用。
0 0
- 关于基类和派生类之间的指针混合的思考
- 关于基类与派生类之间对象、指针等转化关系的小结
- 关于基类与派生类之间对象、指针等转化关系的小结
- 关于C++基类、派生类的引用和指针
- 基类指针和派生类指针的使用总结
- 关于指向派生类的基类指针或引用
- 关于c++派生类构造函数的思考
- 基类和派生类对象之间的赋值
- 派生类和基类之间的特殊关系
- 类型转换-基类和派生类之间的转换
- 基类和派生类对象之间的赋值(截断)
- 基类和派生类之间的关系
- 派生类和基类之间的关系
- c++ 派生类和基类之间的特殊关系
- 公有派生(公有继承) 及 该派生类和基类之间的特殊关系
- 派生类和基类指针的一些使用方法
- 关于C++基类、派生类的引用和指针(动态绑定和静态绑定)
- 基类指针、派生类指针指向基类对象和派生类对象的4种方式
- 【实用随记】点击出现新的DIV,以及点一下转一下
- NSArray 排序
- The basics of using ui-router with AngularJS
- 如何调整c盘分区大小,怎样把c盘空间调整小些
- ffmpeg命令行jpg转png出错求助
- 关于基类和派生类之间的指针混合的思考
- Android自动化测试之Monkeyrunner解决ID重复问题
- oracle安装教程
- php中通过smtp发邮件的类,测试通过
- 在不损坏数据的情况下给WIN7重新划分分区
- CF 392 B. Tower of Hanoi 记忆化搜索
- Three matrices
- HDU 2167 Pebbles_状压求点集的最大权值和
- 根据id生成不重复的邀请码