【发布时间】:2013-08-07 08:29:09
【问题描述】:
当我从std::map 中删除一个元素时,如果调用了默认析构函数,我很好奇。这是我做的一个例子:
class CTestMap{
public:
CTestMap() {
std::cout << "default constructor called" << std::endl;
}
CTestMap(int id) {
std::cout << "created object: " << id << std::endl;
m_id = id;
}
~CTestMap() {
std::cout << "destroyed object: " << this->m_id << std::endl;
}
int get_id(){
return m_id;
}
int m_id;
};
int main(void){
std::map<int, CTestMap>m;
std::map<int, CTestMap>::iterator m_it;
std::cout << "created map " << std::endl;
CTestMap t1(1);
std::cout << "created test object: " << t1.get_id() << std::endl;
CTestMap t2(2);
std::cout << "created test object: " << t2.get_id() << std::endl;
CTestMap t3(3);
std::cout << "created test object: " << t3.get_id() << std::endl;
m[1] = t1;
m_it = m.find(1);
std::cout << "inserted test object: " << m_it->second.get_id() << std::endl;
m[2] = t2;
m_it = m.find(2);
std::cout << "inserted test object: " << m_it->second.get_id() << std::endl;
m[3] = t3;
m_it = m.find(3);
std::cout << "inserted test object: " << m_it->second.get_id() << std::endl;
m_it = m.find(1);
std::cout << "will now erased test object: " << m_it->second.get_id() << std::endl;
m.erase(m.find(1));
std::cout << "erased test object: " << m[1].get_id() << std::endl;
m_it = m.find(1);
std::cout << "object shall no longer exist: " << m_it->second.get_id() << std::endl;
while(1);
return 0;
}
这里是输出:
./htest
created map
created object: 1
created test object: 1
created object: 2
created test object: 2
created object: 3
created test object: 3
default constructor called
destroyed object: 9377935
destroyed object: 9377935
inserted test object: 1
default constructor called
destroyed object: 9377935
destroyed object: 9377935
inserted test object: 2
default constructor called
destroyed object: 9377935
destroyed object: 9377935
inserted test object: 3
will now erased test object: 1
destroyed object: 1
default constructor called
destroyed object: 158830600
destroyed object: 158830600
erased test object: 158830600
object shall no longer exist: 158830600
问题是:
- 为什么调用了这么多次默认构造函数,而我只是 使用我自己的构造函数创建 3 个对象?
- 我可以吗,基于
这个例子说,每次我从
std::map,它的析构函数叫做 ?这是一个普遍的行为吗std::map?我找不到此信息。 - 如果我存储指向对象的指针(我使用'new' 运算符创建它们)怎么办?那么什么时候应该调用
delete?
【问题讨论】:
-
让你的拷贝构造函数和拷贝赋值运算符也打印出来,你会看到的。如果您的编译器支持移动语义,请对移动构造函数和移动赋值运算符执行类似操作。
-
您可能需要创建一个复制构造函数来更好地理解这一点。
-
@MarkGarcia 即使编译器支持移动语义,如果对象具有用户定义的复制构造函数,它也不会使用它们。只需定义复制构造函数就足以初步了解。 (
std::map从来不使用赋值,我认为在 C++11 中已删除了 Assignable 要求。) -
@MarkGarcia 当然,表达式
m[1] = t1;使用赋值运算符(在std::map之外)。