7

std::map使用时会在元素上调用析构函数std::map::clear吗?

我试图调试std::map<string,string>但看不到std::string析构函数被调用。任何人都可以帮助我理解吗?

文档说明它被调用了,但我没有注意到它。

4

4 回答 4

5

文档是正确的,它确实被调用了。

销毁将由方法完成std::allocator<T>::deallocate()。在调试器中跟踪它。

http://www.cplusplus.com/reference/std/memory/allocator/

于 2012-11-17T07:55:35.500 回答
5

析构函数确实被调用了。下面是一个例子来说明:

#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 函数来调用的。

于 2012-11-17T08:13:02.873 回答
0

尝试使用std::map<A,B>whereA并且B是自定义类型,它们具有在其中设置断点的析构函数。你会看到它确实被调用了,以及这个破坏发生在什么范围内。

于 2012-11-17T07:59:43.273 回答
0

这是一个完整的测试,基于 Chris Mansley 的代码,因为我想看看对值、ptrs 和 refs 的影响——我想看看 clear 和 erase 之间的区别。没有不同。总之,析构函数只为值类型调用,这是您所期望的。我只是想检查一下我的理解 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
于 2019-09-21T13:40:56.350 回答