std::map::clear 和 elements' 析构函数
std::map::clear and elements' destructors
当使用析构函数时,std::map::clear
是否会在元素上调用std::map
?
我尝试调试std::map<string,string>
但看不到std::string
析构函数被调用。任何人都可以帮助我理解吗?
文档指出它被调用,但我没有注意到它。
文档是正确的,它确实被调用了。
销毁将通过方法完成 std::allocator<T>::deallocate()
.在调试器中跟踪它。
http://www.cplusplus.com/reference/std/memory/allocator/
析
构函数确实被调用。下面是一个示例来说明:
#include <iostream>
#include <map>
class A
{
public:
A() { std::cout << "Constructor " << this << std::endl; }
A(const A& other) { std::cout << "Copy Constructor " << this << std::endl; }
~A() { std::cout << "Destructor " << this <<std::endl; }
};
int main()
{
std::map<std::string, A> mp;
A a;
mp.insert(std::pair<std::string, A>("hello", a));
mp.clear();
std::cout << "Ending" << std::endl;
}
这将报告类似于以下内容的输出:
Constructor 0xbf8ba47a
Copy Constructor 0xbf8ba484
Copy Constructor 0xbf8ba48c
Copy Constructor 0x950f034
Destructor 0xbf8ba48c
Destructor 0xbf8ba484
Destructor 0x950f034
Ending
Destructor 0xbf8ba47a
因此,您可以看到析构函数是通过调用 clear 函数来调用的。
尝试使用std::map<A,B>
,其中A
和B
是具有已设置断点的析构函数的自定义类型。您将看到它确实被调用,以及此销毁发生在什么范围内。
这是一个更完整的测试,建立在 Chris Mansley 的代码之上,因为我想看看对值、ptrs 和 refs 的影响 - 我想看看有什么不同在清除和擦除之间。没有区别。总之,析构函数只被调用对于您期望的值类型。我只是想检查我的理解 8)
#include <iostream>
#include <map>
class A
{
public:
std::string some_data;
A(std::string some_data) : some_data(some_data) {
std::cout << " A(" << some_data << ") @" << this << std::endl;
}
A(const A& other) {
some_data = other.some_data;
std::cout << " Copy A(" << other.some_data << ") @" << this << std::endl;
}
~A() {
std::cout << " Destruct ~A(" << some_data << ") @" << this << std::endl;
}
};
void clear_test_value (void)
{
std::cout << "clear_test_value() {" << std::endl;
std::map<std::string, A> mp;
A a("A1 data");
mp.insert(std::pair<std::string, A>("key1", a));
mp.clear();
std::cout << "}" << std::endl;
std::cout << std::endl;
}
void erase_test_value (void)
{
std::cout << "erase_test_value() {" << std::endl;
std::map<std::string, A> mp;
A a("A1 data");
mp.insert(std::pair<std::string, A>("key2", a));
auto f = mp.find("key2");
if (f == mp.end()) {
std::cout << "failed to find element {" << std::endl;
return;
}
mp.erase(f);
std::cout << "}" << std::endl;
std::cout << std::endl;
}
void clear_test_ptr (void)
{
std::cout << "clear_test_ptr() {" << std::endl;
std::map<std::string, A*> mp;
A a("A1 data");
mp.insert(std::pair<std::string, A*>("key1", &a));
mp.clear();
std::cout << "}" << std::endl;
std::cout << std::endl;
}
void erase_test_ptr (void)
{
std::cout << "erase_test() {" << std::endl;
std::map<std::string, A*> mp;
A a("A1 data");
mp.insert(std::pair<std::string, A*>("key2", &a));
auto f = mp.find("key2");
if (f == mp.end()) {
std::cout << "failed to find element {" << std::endl;
return;
}
mp.erase(f);
std::cout << "}" << std::endl;
std::cout << std::endl;
}
void clear_test_ref (void)
{
std::cout << "clear_test_ref() {" << std::endl;
std::map<std::string, A&> mp;
A a("A1 data");
mp.insert(std::pair<std::string, A&>("key1", a));
mp.clear();
std::cout << "}" << std::endl;
std::cout << std::endl;
}
void erase_test_ref (void)
{
std::cout << "erase_test_ref() {" << std::endl;
std::map<std::string, A&> mp;
A a("A1 data");
mp.insert(std::pair<std::string, A&>("key2", a));
auto f = mp.find("key2");
if (f == mp.end()) {
std::cout << "failed to find element {" << std::endl;
return;
}
mp.erase(f);
std::cout << "}" << std::endl;
std::cout << std::endl;
}
int main ()
{
clear_test_value();
erase_test_value();
clear_test_ptr();
erase_test_ptr();
clear_test_ref();
erase_test_ref();
return (0);
}
输出:
clear_test_value() {
A(A1 data) @0x7ffee07389a0
Copy A(A1 data) @0x7ffee0738960
Copy A(A1 data) @0x7fe98fc029c8
Destruct ~A(A1 data) @0x7ffee0738960
Destruct ~A(A1 data) @0x7fe98fc029c8
}
Destruct ~A(A1 data) @0x7ffee07389a0
erase_test_value() {
A(A1 data) @0x7ffee07387f0
Copy A(A1 data) @0x7ffee07387b0
Copy A(A1 data) @0x7fe98fc029c8
Destruct ~A(A1 data) @0x7ffee07387b0
Destruct ~A(A1 data) @0x7fe98fc029c8
}
Destruct ~A(A1 data) @0x7ffee07387f0
clear_test_ptr() {
A(A1 data) @0x7ffee07389b0
}
Destruct ~A(A1 data) @0x7ffee07389b0
erase_test() {
A(A1 data) @0x7ffee0738800
}
Destruct ~A(A1 data) @0x7ffee0738800
clear_test_ref() {
A(A1 data) @0x7ffee07389b0
}
Destruct ~A(A1 data) @0x7ffee07389b0
erase_test_ref() {
A(A1 data) @0x7ffee0738800
}
Destruct ~A(A1 data) @0x7ffee0738800
相关文章:
- 什么时候调用组成单元对象的析构函数
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 内联映射初始化的动态atexit析构函数崩溃
- 什么时候调用析构函数
- 优先顺序:智能指针和类析构函数
- C++-明确何时以及如何调用析构函数
- 使用基类指针创建对象时,缺少派生类析构函数
- 在c++中使用向量时,如何调用构造函数和析构函数
- 重载运算符new[]的行为取决于析构函数
- 我需要知道编译器如何在cpp中使用析构函数
- 为什么在使用转换构造函数赋值后调用C++类的析构函数?
- 析构函数调用
- 通过引用传递-为什么要调用这个析构函数
- 对具有动态分配的内存和析构函数的类对象的引用
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- 如何为包含map<int,*double>成员的类编写析构函数?
- std::map::clear 和 elements' 析构函数
- std:map 析构函数是否调用键析构函数以及值析构函数?
- std::map如何调用值析构函数
- std::map<struct, int> 我需要析构函数吗?