社区
C语言
帖子详情
STL容器能否包含多态类型,如果可以的话,怎样才能做到安全有效?
anrxhzh
2002-04-12 02:45:04
希望定义一个容器能够包含整个类层次中的所有非抽象类的对象。
...全文
260
21
打赏
收藏
STL容器能否包含多态类型,如果可以的话,怎样才能做到安全有效?
希望定义一个容器能够包含整个类层次中的所有非抽象类的对象。
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
21 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
anrxhzh
2002-04-12
打赏
举报
回复
我又搞错了,shared_ptr<T>中的T可以为抽象基类,它只是要求T的析构函数必须为public。
在类工厂模式下析构函数为protected或者private是很常见的,在那种情况下就需要其他方法了,我想那时使用http://www.xraylith.wisc.edu/~khan/software/stl/STL.newbie.html#pointer_deriv 上的方法就显得很自然了,类工厂和容器的例子在More Effective C++ Item 25上也有论述。
好了,终于可以告一段落了,谢谢大家的帮忙。
anrxhzh
2002-04-12
打赏
举报
回复
to babysloth(小懒虫虫) :
非常感谢你的解答,我想你是对的。看来我把这个问题理解错了,这不是一个多态的问题,而是一个管理指针的问题。其实就算什么都不想,直接把指针放到容器里,也不会在多态上造成问题,因为所有跟多态有关的实现细节都已经被编译器藏到了指针里,我真是杞人忧天。
真正的问题出现如何对容器中的指针进行管理上,假如直接把指针放到容器里,然后在进行删除元素操作和容器的析构器中释放元素指向的内存,听起来似乎井井有条,但是如果一个容器中有多个元素指向同一个对象或者多个指向同一个对象的元素被包含到多个容器中,就会带来一片混乱。
那么用标准库中的auto_ptr来管理指针又会如何呢?情况可能会更糟,不但老问题不能解决,还带来了新问题,auto_ptr只是简单的将指针的管理权在对象之间转移,假如在对容器进行操作的算法中将元素的管理权交给了临时对象,那么当算法完成后临时对象将自动地释放该元素指向的内存,结果将不堪设想。
终于轮到shared_ptr登场了,这个比auto_ptr复杂得多的东东管理的是对象的引用计数,当计数为0时自动释放内存,呵呵,真是个好管家。
上面啰嗦了这么多,主要是给自己看,不把它写出来我始终觉得脑子很乱。
言归正传,shared_ptr<T>要求T不能为抽象基类并且能够访问T的析构函数,这就造成了绝大多数基类不能被使用。
革命尚未成功,同志还须努力。
挺拔的劲松
2002-04-12
打赏
举报
回复
应该保存指针才行吧!
babysloth
2002-04-12
打赏
举报
回复
问题复杂的原因是被我们搞复杂了。
问题本身是简单的。
stl容器的设计者还没笨到连这个问题都没考虑。
对于我上面那段代码
for(list_type::iterator i = ll.begin(); i != ll.end(); ++i)
i->InterfaceOfBase();
也是多态调用。
shared_ptr是对指针的包装!
babysloth
2002-04-12
打赏
举报
回复
2 anrxhzh
您恐怕还没明白我写的那段代码
那里面储存的是指针,何来类型丢失???
anrxhzh
2002-04-12
打赏
举报
回复
我估计是要使用Abstract Factory之类的重型武器了。
anrxhzh
2002-04-12
打赏
举报
回复
babysloth(小懒虫虫) 的方法是有问题的,原因在于容器认为其包含所有对象都是基类对象,这样肯定会造成类型丢失,这就是Scott Meyers所讲的Never treat arrays polymorphically 。
我把问题详细地描述一下:
存在一个单根的类层次,基类为抽象类Base。
要求实现容器类Container,满足一下要求:
1.可以包含所有非抽象的子类对象。
2.Container不必知道类层次的具体结构,也不必知道Base的接口。
3.对容器对象进行操作不能造成类型丢失。
客户可以编写这样的代码:
void Test(Container& c)
{
for(Container::iterator i(c.begin());i<c.end();++i)
(*i).InterfaceOfBase();
}
全部的奥妙在于对InterfaceOfBase的调用是多态的。
babysloth
2002-04-12
打赏
举报
回复
这段代码在gcc、vc、bcc里都没有问题。
2 prototype
好象不是限制模板参数的问题吧^_^
babysloth
2002-04-12
打赏
举报
回复
列代码出来吧,呵呵,看看是不是这个意思
#include <list>
#include <boost/shared_ptr.hpp>
class A{};
class C: public A{};
int main()
{
typedef boost::shared_ptr<A> element_type;
typedef std::list<element_type> list_type;
list_type ll;
ll.push_back(element_type(new C));
}
prototype
2002-04-12
打赏
举报
回复
to anrxhzh(百宝箱):
i read the other posts and realized my understanding of your problem might be different than the others's.
here is my understanding:
you have:
class A;
class B : public A;
class C : public B;
template <typename T>
class container;
you want that 'T' should only be allowed to be 'A', 'B', 'C', not any other types.
if this is your problem ...
babysloth
2002-04-12
打赏
举报
回复
呵呵,抱歉,没看清楚。
shared_ptr不只是解决共享的问题,事实上,这里也没有这个问题。
我的意思是,把基类的指针放进shared_ptr,再把shared_ptr作为容器放进容器就可以了。
anrxhzh
2002-04-12
打赏
举报
回复
希望大家看看已有的解决方案,应该有启发意义。
http://www.xraylith.wisc.edu/~khan/software/stl/STL.newbie.html#pointer_deriv
neccui
2002-04-12
打赏
举报
回复
你没理解我的意思。
我的意思是, 一个给定参数的容器里面的对象大小是固定的。
anrxhzh
2002-04-12
打赏
举报
回复
to babysloth(小懒虫虫):
shared_ptr 解决的是共享对象的问题,而不是多态的问题,这是两个完全不同的问题,仅依靠模板肯定是不能解决多态问题的。
babysloth
2002-04-12
打赏
举报
回复
容器要求大小固定?不是吧?
neccui
2002-04-12
打赏
举报
回复
容器虽然不是数组,但是也是要求大小固定的,这个就没法解决。
babysloth
2002-04-12
打赏
举报
回复
用boost库里的shared_ptr包装好,直接往容器里放就可以了。
这也是boost:shared_ptr设计的初衷之一。
anrxhzh
2002-04-12
打赏
举报
回复
to afsfop:
我明白多态容器将带来很多麻烦,但是有时确实需要它,就像多重继承一样。容器!=数组,所以应该不存在Scott Meyers所讲的限制。我在
http://www.xraylith.wisc.edu/~khan/software/stl/STL.newbie.html#pointer_deriv
上找到了两种实现方法,可惜都需要修改类层次的现有接口,不知道有没有更完美的解决方案。
to prototype:
希望能详细地讲一下,多谢。
boyfling
2002-04-12
打赏
举报
回复
http://www.csdn.net/expert/topic/639/639286.xml?temp=8.961123E-02
prototype
2002-04-12
打赏
举报
回复
one way for takling this problem is to use typelist and static assertion (+ a little bit template meta-programming knowledge).
another is to use typetraits (maybe better?).
加载更多回复(1)
C++
STL
: map自定义键值
类型
本文探讨了在C++
STL
的unordered_map中使用自定义键值
类型
的三种方法,包括重载operator<(),自定义比较函数对象,以及less函数的模板定制,帮助理解如何在复杂数据结构中实现键值对的
有效
管理和比较。
【C++核心技术深度解析:从继承
多态
到
STL
容器
】
本文深入解析C++核心技术,涵盖继承机制、
多态
、二叉搜索树(BST)和
STL
容器
。介绍了继承的基础概念、多继承问题及解决方案,阐述
多态
的实现条件与机制,讲解BST的性质、操作和应用场景,还分析了
STL
容器
的特点和适用场景,并汇总面试高频问题和最佳实践。
C++
STL
笔记一:初识
STL
;
容器
;算法;迭代器;
容器
装数据
本文详细介绍了C++中的
STL
(标准模板库),包括其起源、基本概念和主要组件。
STL
通过
容器
(如vector、list等)、算法(如sort、find等)和迭代器提供了高效的数据管理和处理方式。
容器
中的数据可以通过迭代器访问,而算法则通过迭代器在
容器
上执行操作。此外,文章还探讨了不同
类型
的迭代器及其功能,并展示了如何使用
STL
进行代码复用和简化编程任务。
突破
STL
的
多态
壁垒:将
多态
函数对象传递给算法
本文聚焦 C++ 中面向对象编程与
STL
的碰撞,探讨如何将
多态
函数对象传递给
STL
算法。介绍了
多态
函数对象概念,指出按值传递会导致对象切割、
多态
行为丢失。提出使用 lambda 表达式和 std::ref 两种解决方案,对比后认为 std::ref 更简洁高效。
c++:
STL
之顺序
容器
,关联
容器
,顺序
容器
适配器
本文深入解析C++标准模板库(
STL
),涵盖
STL
的核心概念、组件及应用,详细阐述顺序
容器
、关联
容器
与适配器的特性与操作方法,为C++程序员提供全面的
STL
指南。
C语言
70,039
社区成员
243,246
社区内容
发帖
与我相关
我的任务
C语言
C语言相关问题讨论
复制链接
扫一扫
分享
社区描述
C语言相关问题讨论
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章