免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5017 | 回复: 9
打印 上一主题 下一主题

[C++] 直接操作对象和用指针、引用操作对象的区别 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-01-11 10:23 |只看该作者 |倒序浏览
我在学习的时候看到这样的内容:

实现多态,必须通过指针或者引用去操作对象,如果直接操作对象,它的类型就已经为编译器所知,也就无法实现多态了。


直接操作对象和用指针、引用操作对象到底有什么内在的区别?

能否从内存的分配,编译等方面解释下?

论坛徽章:
0
2 [报告]
发表于 2010-01-11 10:38 |只看该作者
父类的指针是可以指向子类类型的,父类对象也是可以引用子类对象的
通过这个可以让父类使用子类的方法,这个就是多态

这个和继承的内存构建有关
class  A {...};
class  B : public A {...};
如果生成一个B的对象b,是先构建A再构建B,b的内存空间结构就是A在上B在下
所以A的指针是可以指向b的

论坛徽章:
0
3 [报告]
发表于 2010-01-11 10:42 |只看该作者
原帖由 shmild 于 2010-1-11 10:38 发表
父类的指针是可以指向子类类型的,父类对象也是可以引用子类对象的
通过这个可以让父类使用子类的方法,这个就是多态

这个和继承的内存构建有关
class  A {...};
class  B : public A {...};
如果生成一 ...

大体理解了,但是还想深究一下,为啥B(子类)的指针不能指向A(父类)的对象?

论坛徽章:
0
4 [报告]
发表于 2010-01-11 10:48 |只看该作者
我google一下,解释为:

子类的内存空间通常大于父类,如果子类的指针指向父类,就意味着它可以操作大于父类地址范围之外的空间,非常危险,所以被禁止。

[ 本帖最后由 smartvessel 于 2010-1-11 10:50 编辑 ]

论坛徽章:
0
5 [报告]
发表于 2010-01-11 10:51 |只看该作者
原帖由 smartvessel 于 2010-1-11 10:42 发表

大体理解了,但是还想深究一下,为啥B(子类)的指针不能指向A(父类)的对象?

因为子类对象内存空间比父类的长啊,试过可以反过来指,会有很恐怖的事情

论坛徽章:
0
6 [报告]
发表于 2010-01-11 10:52 |只看该作者
能解释下:
父类的指针为啥可以指向子类类型的?
父类引用对象为啥可以引用子类对象的?

怎么实现的?

这个好像比较钻牛角尖了

论坛徽章:
0
7 [报告]
发表于 2010-01-11 10:53 |只看该作者

回复 #5 shmild 的帖子

你说的对

论坛徽章:
0
8 [报告]
发表于 2010-01-11 11:02 |只看该作者
如果子类指针指向夫类对象,那么如果访问子类特有的成员时会出问题。
例如:
class  A {
public:
  int a;
};
class  B : public A {
public:

  int b;
};

main()
{
    B* obj = (B*)(new A);
    obj->b = 0;//由于A类对象没有成员b,这样就会出错。
}

另外,多态只能通过指针和引用使用只是C++的特性,Java就不需要,直接用对象就可以多态。因为C++还不是那么动态而已。

论坛徽章:
0
9 [报告]
发表于 2010-01-11 11:17 |只看该作者

回复 #8 gz80 的帖子

C++的多态需要指针或引用,加上虚函数实现,跟Java差别的确比较大。

论坛徽章:
0
10 [报告]
发表于 2010-01-11 11:27 |只看该作者
原帖由 smartvessel 于 2010-1-11 11:17 发表
C++的多态需要指针或引用,加上虚函数实现,跟Java差别的确比较大。

#include <iostream>
using namespace std;
class A
{
public:
&nbsp;&nbsp;&nbsp;&nbsp; virtual void s_print(){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout<<"A"<<endl;
&nbsp;&nbsp;&nbsp;&nbsp;}
};

class B:public A
{
&nbsp;&nbsp;&nbsp;&nbsp;void s_print(){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout<<"B"<<endl;
&nbsp;&nbsp;&nbsp;&nbsp;}
};
int main() {

&nbsp;&nbsp;&nbsp;&nbsp;A* a = new B;
&nbsp;&nbsp;&nbsp;&nbsp;a->s_print();
&nbsp;&nbsp;&nbsp;&nbsp;return 0;
}


用父类指针去操作子类,例如A* a = new B;
实际上就是通知a,如果a调用函数,先看看是否是虚函数,如果是直接在虚函数表中找到并调用,不是虚函数,就调用自己的函数。
子类的每一次继承A,如果要实现多态,都要自己实现虚函数virtual,这样编译时,父类在其自身的虚函数表中更新。

不知这样理解是否有问题?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP