将派生类作为值放入STL映射中
Putting derived classes into STL maps as values
我有两个简单的类。基类A
和派生类B
。出于调试目的,复制构造函数和析构函数被重写为cout
内容:
class A
{
protected:
char * c;
public:
A(char * c) : c(c) { cout << "+A " << this << "n"; }
A(const A& other) : c(other.c) { cout << "*A " << this << "n"; }
~A() { cout << "-A " << this << "n"; }
};
class B : public A
{
public:
B(char * c) : A(c) { cout << "+B " << this << "n"; }
B(const B& other) : A(other.c) { cout << "*B " << this << "n"; }
~B() { cout << "-B " << this << "n"; }
};
以下是我如何将insert
的一个实例B
map
:
{
cout << "-- 1n";
map<string, A> m;
cout << "-- 2n";
m.insert(pair<string, A>( "b", B("bVal")));
cout << "-- 3n";
}
cout << "-- 4 --n";
结果:
-- 1
-- 2
+A 0051F620
+B 0051F620
*A 0051F5EC
*A 00BD8BAC
-A 0051F5EC
-B 0051F620
-A 0051F620
-- 3
-A 00BD8BAC
-- 4 --
关于实例的创建,我阅读如下:
B
由我自己的代码创建- CCD_ 8被CCD_
- 最后一个
A
实例然后被插入的map
再次复制
顺便说一句,将insert
行中的pair
更改为pair<string, B>
并没有起到什么作用,它只是将第二步更改为创建B
而不是A
,但最后一步会将其再次降级为A
。在映射本身符合销毁条件之前,映射中唯一保留的实例似乎是最后一个A
实例。
我做错了什么?我应该如何将派生类放入映射中?使用格式的地图
map<string, A*>
也许吧?
更新-解决方案由于我的解决方案没有直接在接受的答案中说明,而是以建议的形式隐藏在其评论中,因此我最终要做的是:
map<string, shared_ptr<A>> m;
这假设您的构建环境支持shared_ptr
,而我的(C++/CLI,Visual Studio 2010)支持CCD_ 20。
这被称为切片,当派生类不适合它所分配的对象时就会发生这种情况
B b;
A a = b; // This would only copy the A part of B.
如果要在地图中存储不同类型的对象,请使用map<。。。,正如你正确推断的那样,A**是前进的道路。由于对象不是存储在映射中,而是存储在堆中的某个位置,因此不需要复制它,而且它总是适合的。
map<string, A> m;
将切片插入的对象,该对象将成为A
,丢失所有其他信息(不再是B
)。
你的直觉是正确的,你需要使用指针,或者更好的是,使用智能指针。
此外,A
中的析构函数需要是virtual
:
class A
{
//...
virtual ~A() { cout << "-A " << this << "n"; }
};
否则通过指向CCD_ 26的指针删除实际类型为CCD_。
相关文章:
- STL映射比较器能否以某种方式获取指向映射本身的指针?
- 在 c++ stl 映射中,删除具有重复值的条目
- C++ STL 映射同时更新所有值
- 遍历 STL 映射(集/多集)的最佳方法,同时元素可能会在循环期间被删除并重新插入?
- 无法将元素添加到 STL 映射
- 为什么不能在STL映射中插入值
- 在 stl 映射和列表 (c++) 上进行迭代的泛型循环
- 未签名的char数组到stl ::映射或其他容器中的键
- 整数和元组的静态 STL 映射返回 0
- 指向类的指针的 STL 映射的 SWIG 类型图
- 将 STL 映射存储到 Boost ConstBufferSequence 中
- 如何在下一次函数调用中使用 STL 映射擦除从最后一个位置
- 如何使用密钥 2 更新 STL 映射键 1 并将值复制到键 2 中
- 为什么当代码尝试在 STL 映射中查找键时出现分段错误
- 快速插入STL映射
- C STL映射中的SegFault由于过程退出期间的静态可变清理而找到
- 如何将 STL 映射保存到文件C++
- C++STL映射键和值工作不正常
- STL 映射自定义比较器
- 带有内存比较的 STL 映射.如何在运行时设置比较块大小