C++ C++;带指针的STL容器:几个问题
假设您有一个类型C++ C++;带指针的STL容器:几个问题,c++,pointers,stl,subclass,C++,Pointers,Stl,Subclass,假设您有一个类型T和子类型TSub1,TSub2等 这些亚型中有几个是用新的TSub(…)初始化的。生成的指针随后作为元素存储在: list<T*> tsList; list-tsList; 相同的指针也用作以下中的键: map<T*,V> tsMap; map-tsMap; 现在考虑一个关于 TSList的迭代,用迭代器变量滴度 < < /P> 以下是我的问题: 将tsMap[*滴度]和tsMap.find(*滴度)都成功 是否找到正确的关联值 将删除*tIte
T
和子类型TSub1
,TSub2
等
这些亚型中有几个是用新的TSub(…)
初始化的。生成的指针随后作为元素存储在:
list<T*> tsList;
list-tsList;
相同的指针也用作以下中的键:
map<T*,V> tsMap;
map-tsMap;
现在考虑一个关于<代码> TSList的迭代,用迭代器变量<代码>滴度 < < /P> 以下是我的问题:
tsMap[*滴度]
和tsMap.find(*滴度)
都成功
是否找到正确的关联值删除*tIter
成功释放整个内存块
即使STL认为类型为
T
T::foo()
并重写TSub::foo()
将(*滴度)->foo()
调用T::foo()
或TSub::foo()
TSub
都需要以单例方式实例化,但存储方式允许迭代考虑作为超类型,并在被调用的子类中重写方法
如果能给我一个明智的解释,我将不胜感激。谢谢你抽出时间
tsMap[*滴度]和tsMap.find(*滴度)是否都能成功找到
正确的关联值
是的,但是如果tsMap[*滴度]没有找到密钥,它将创建一个默认值
delete*tIter将成功释放分配的全部内存块
对于相关的TSub,即使STL将类型视为T
当且仅当T的析构函数是虚的
假设有一个已定义的方法T::foo()并重写TSub::foo()
Will(*tIter)->foo()调用T::foo()或TSub::foo()
如果T::foo不是虚拟的,它将调用T::foo。否则它将调用TSub::foo()我建议从boost中查看
此外,我建议
tsMap[*滴度]和tsMap.find(*滴度)是否都能成功找到正确的关联值
取决于成功的定义。如果指针标识是键标识,则为“是”。如果需要比较指针对象,则需要提供一个比较器函数对象(c++0x中的可调用类型)
相当低效的PoC:(见)
#包括
#包括
模板
静态布尔无间接(常数T*a,常数T*b)
{
如果(a==b)
返回false;
如果(!a)
返回true;
如果(!b)
返回false;
返回std::less()(*a,*b);
}
typedef int T;
typedef int V;
int main()
{
类型定义布尔(*cmp_t)(常数t*,常数t*);
std::map tsMap(&无间接);
}
如果你能发布一些代码/演示代码来解释你的问题,会更容易。我的问题非常清楚,Gob00st。一个有经验的C++程序员将能够给我一个答案。@ KomodoDave,当你提到一个“普通的虚拟回避技巧”时,看到一些代码仍然是很好的。你是指CRTP(这个缩写词对一个有经验的C++程序员来说更容易理解吗?)?@基督教——是的,我指的是CRTP,但是我已经编辑了这个信息,因为我意识到如果你有<代码> T <代码>,<代码> T >代码>等等,就不可能创建一个<代码>列表>代码。因此,<代码>虚拟<代码>是必要的。谢谢:)一个完美而令人愉快的回答,非常感谢你,的确是Armen:)谢谢你提供的额外信息,sehe。在我的情况下,我不需要比较指向的对象,否则我会这么说;我提到辛格尔顿时应该说得很清楚。我也不喜欢使用Boost,我更喜欢香草C++。
#include <map>
#include <functional>
template <typename T>
static bool indirectLess(const T* a, const T* b)
{
if (a==b)
return false;
if (!a)
return true;
if (!b)
return false;
return std::less<T>()(*a, *b);
}
typedef int T;
typedef int V;
int main()
{
typedef bool (*cmp_t)(const T*, const T*);
std::map<T*,V,cmp_t> tsMap(&indirectLess<T>);
}