std::map、多态和删除
我在使用 C++ 映射存储指向基类和某些派生类的指针时遇到问题。
让我用一个相当长但简单的代码来解释:
#include <map>
#include <iostream>
struct foo{ int dummy[4]; };
struct bar{ int additionnal[4]; };
class Base
{
private:
struct foo *_internal_structure;
public:
Base() { _internal_structure = new struct foo; }
~Base()
{
delete _internal_structure;
std::cout << "Base DTOR\n";
}
};
class Derived: public Base
{
private:
struct bar *_additional_structure;
public:
Derived() { _additional_structure = new struct bar; }
~Derived()
{
delete _additional_structure;
std::cout << "Derived DTOR\n";
}
};
int main(int argc, char *argv[])
{
std::map<int, Base*> my_map;
Base *to_add = new Base();
Derived *derived_to_add = new Derived();
my_map[1] = to_add;
my_map[2] = derived_to_add; // works, derived class, but object gets sliced
/// clear hash map ///
std::map<int, Base*>::const_iterator iter;
for(iter = my_map.begin(); iter != my_map.end(); ++iter)
{
delete (*iter).second;
}
return 0;
}
运行结果:
Base DTOR
Base DTOR
所以,事情是,当我将 Derived 类指针插入到我的映射中时,底层对象被视为 Base< /em> 类;因此调用的析构函数是基类的析构函数,而不是派生类的析构函数。 Valgrind 确认我每次都会丢失 16 个字节。
另外,我无法使用Boost的shared_ptr(我在这里看到了一些提及),并且我使用的嵌入式架构不支持 C++ 异常和 RTTI (在我的例子中,这会导致一些未对齐的访问和其他不良情况)东西)(编辑:不相关)。
你知道我该如何解决这个问题吗?
I have a problem using a C++ map to store pointers to a base class and some derived class.
Let me explain by a rather long but simple code:
#include <map>
#include <iostream>
struct foo{ int dummy[4]; };
struct bar{ int additionnal[4]; };
class Base
{
private:
struct foo *_internal_structure;
public:
Base() { _internal_structure = new struct foo; }
~Base()
{
delete _internal_structure;
std::cout << "Base DTOR\n";
}
};
class Derived: public Base
{
private:
struct bar *_additional_structure;
public:
Derived() { _additional_structure = new struct bar; }
~Derived()
{
delete _additional_structure;
std::cout << "Derived DTOR\n";
}
};
int main(int argc, char *argv[])
{
std::map<int, Base*> my_map;
Base *to_add = new Base();
Derived *derived_to_add = new Derived();
my_map[1] = to_add;
my_map[2] = derived_to_add; // works, derived class, but object gets sliced
/// clear hash map ///
std::map<int, Base*>::const_iterator iter;
for(iter = my_map.begin(); iter != my_map.end(); ++iter)
{
delete (*iter).second;
}
return 0;
}
Result when run:
Base DTOR
Base DTOR
So, thing is, when I insert a Derived class pointer into my map, the underlying object is considered as a Base class; so the destructor called is the one of the Base class, and not the Derived class. Valgrind confirms me that I loose 16 bytes every time.
Also, I can't use Boost's shared_ptr (I saw some mentions of it here), and the embedded architecture I use doesn't support C++ exceptions and RTTI (which in my case, causes some unaligned accesses and other bad stuff)(edit: not related).
Do you know how I can fix this behavior?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你的虚拟析构函数在哪里???!!!
阅读本文,并且永远忘记。真的,你刚刚违反了 10 条 C++ 戒律之一......:))
Where is your virtual destructor???!!!
Read this, and never forget. Really, you have just broken one of the 10 C++ commandments... :))
任何基类中的析构函数都应该是虚拟。
否则,在通过指向其基类的指针引用子类的情况下,不可能在运行时确定实际应该调用哪些析构函数。
Your destructor in any base class should be virtual.
Otherwise it's impossible at runtime to determine what destructor(s) should actually be called, in the case where subclasses are referenced through a pointer to their base class.