免费注册 查看新帖 |

Chinaunix

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

[C++] 小小请教一下:vector的引用如何遍历(和类型转换)? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-12-23 17:25 |只看该作者 |倒序浏览
void my::addItems(const vector<Item> &tis){
                 ChildItem        *        ppti = NULL;
        for(vector<Item>::iterator it = tis.begin();it != tis.end();it ++){
                ppti = static_cast<ChildItem *>(it);
               
              ..........
      }

在遍历时,编译器说:
An object or reference of type "std::vector<Item,std::allocator<Item> >::iterator" cannot be initialized with an rvalue of type "std::_Ptrit<Item,long,
const Item *,const Item &,Item *,TItem &>"

好像是说引用不能像我那样遍历。那若我希望遍历要怎么做?

还有那个static_cast,因为ChildItem是Item的子类,本来我是想用dynamic_cast更好些,但因为Item只是个简单类,没有虚函数,所以不让用dynamic_cast,这种情况下是不是只有static_cast这一条路可走?

论坛徽章:
0
2 [报告]
发表于 2008-12-23 18:22 |只看该作者
1. const_iterator
2. (1)const最好不要转换为非const,想想一定需要要这么做么?如果是参数就用不着const引用了,也就不需要const转换
   (2)容器中存放的是基类对象(不是指针也不是引用),把它转换为派生类做啥?
   (3)it != &*it

论坛徽章:
0
3 [报告]
发表于 2008-12-23 18:32 |只看该作者
容器中存着的对象是不定的,只能知道共同属于一个基类,所以需要运行时判断。我略去了一些判断代码而已。
正因为是参数,而且是大对象,所以才需要引用;因为不希望实现更改,所以用const。
那ppti = static_cast<ChildItem *>(it);这句要换成const_cast,难道是ppti = static_cast<ChildItem *>(const_cast<Item *>(it)) 这样写吗?

论坛徽章:
0
4 [报告]
发表于 2008-12-23 19:18 |只看该作者
原帖由 jchc 于 2008-12-23 18:32 发表
容器中存着的对象是不定的,只能知道共同属于一个基类,所以需要运行时判断。我略去了一些判断代码而已。
正因为是参数,而且是大对象,所以才需要引用;因为不希望实现更改,所以用const。
那ppti = static_cast<ChildItem *>(it);这句要换成const_cast,难道是ppti = static_cast<ChildItem *>(const_cast<Item *>(it)) 这样写吗?

1. vector存放的是“基类对象”,不是“指针”也不是“引用”,因此,它存不了派生类对象!(去了解下什么叫对象切片)
2. 既然你不需要修改,那么就应该用const ChildIterm*指针,也就不需要const转换(当然,由于你的对象始终是基类对象,转型已经不着调了)

论坛徽章:
0
5 [报告]
发表于 2008-12-23 19:36 |只看该作者
算我说错。我存的是不同的子类对象,但它们都是Item的子类。为了屏蔽差异,我只能将它们造型成基类。这样是否有错?

论坛徽章:
0
6 [报告]
发表于 2008-12-23 19:52 |只看该作者
原帖由 jchc 于 2008-12-23 19:36 发表
算我说错。我存的是不同的子类对象,但它们都是Item的子类。为了屏蔽差异,我只能将它们造型成基类。这样是否有错?

容器中存的什么是由模板参数决定的,比如vector<Item>存放的对象一定是Item对象,即使传给它派生类对象,也会被转换为基类对象(对象切片)

例子:
class Item
{/*...*/};
class ChildItem: public Item
{/*..*/};

vector<Item> vec;
vec.push_back(Item());
vec.push_back(ChildItem());

上面的向容器中添加了两个元素,虽然有一个是ChildItem对象,但存放在vec中的却是切片后的Item对象

不知道明白没?

论坛徽章:
0
7 [报告]
发表于 2008-12-24 08:10 |只看该作者
那么若希望达到我的目的(可存基类也可存子类),应该如何做呢?(假设不用指针,用引用可否?)

[ 本帖最后由 jchc 于 2008-12-24 08:12 编辑 ]

论坛徽章:
0
8 [报告]
发表于 2008-12-24 09:05 |只看该作者
原帖由 jchc 于 2008-12-23 16:10 发表
那么若希望达到我的目的(可存基类也可存子类),应该如何做呢?(假设不用指针,用引用可否?)


容器不能存引用。只能是指针或是智能指针,比如 shared_ptr。

论坛徽章:
0
9 [报告]
发表于 2008-12-24 09:22 |只看该作者
那这就有个大问题:很多传进来的都只是局部变量(没有new),而且在类内也可能会生成一些东西插入vector并传出,若也用指针就必须全new,这样可能会出现指针作用域问题。

论坛徽章:
0
10 [报告]
发表于 2008-12-24 11:19 |只看该作者
那我是不是用boost::any当元素即可?vector<boost::any> ....这样就一切ok??然后当vector析构时元素自动析构……??
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP