对于自定义类型Student而言,作为Value插入到std::map中,没有写默认构造函数,编译器报错,为了探明原因,就把Student类的几个重要函数都写了出来并且配合qDebug信息输出,找出了真正原因:std::map在插入新值的时候会先调用默认构造函数,然后调用赋值构造函数!
#include <QApplication>
#include <QDebug>
#include <iostream>
#include <string.h>
class Student {
public:
// 默认构造函数(由于下面要插入到std::map,所以默认构造函数必须提供)
Student() {
name_ = new char[1]; //不能赋值为nullptr,因为下面拷贝构造没有判空
*name_ = '\0';
qDebug() << "default constructor called" << endl;
}
// 有参构造函数
Student(const char* name) {
qDebug() << "param constructor called" << endl;
if (name == nullptr) {
name_ = new char[1]; //不能赋值为nullptr,因为下面拷贝构造没有判空
*name_ = '\0';
} else {
int len = strlen(name);
name_ = new char[len+1]; // 这里一定要注意,不要写成(len+1)哦
memcpy(name_, name, len+1);
}
}
// 拷贝构造函数
Student (const Student& other) {
qDebug() << "copy constructor called" << endl;
int len = strlen(other.name_);
name_ = new char[len+1]; // 这里一定要注意,不要写成(len+1)哦
memcpy(name_, other.name_, len+1);
}
// 赋值构造函数
Student& operator= (const Student& other) {
qDebug() << "operator= constructor called" << endl;
if (this == &other) {
return *this;
}
if (name_) {
delete[] name_;
name_ = nullptr;
}
int len = strlen(other.name_);
name_ = new char[len+1]; // 这里一定要注意,不要写成(len+1)哦
memcpy(name_, other.name_, len+1);
return *this;
}
// 析构函数
~Student() {
qDebug() << "destructor called" << endl;
delete[] name_;
name_ = nullptr;
}
// 输出运算符重载
friend ostream& operator<< (ostream &out,const Student& student) {
out << student.name_ << endl;
return out;
}
private:
char* name_;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
std::map<char,Student> mymap;
std::map<char,Student>::iterator it;
// 向std::map里插入值[!注意!]
mymap['a'] = "string_a";// 这里包含了4步:
// 1.调用Student(const char* name)
// 2.调用Student()
// 3.调用Student& operator=(const Student& other)
// 4.调用~Student()
mymap['b'] = "string_b";
mymap['c'] = "string_c";
mymap['d'] = "string_d";
mymap['e'] = "string_e";
mymap['f'] = "string_f";
it = mymap.find('b');
mymap.erase (it); // erase操作会调用~Student()
mymap.erase ('c');
it=mymap.find ('e');
mymap.erase ( it, mymap.end() );
for (it = mymap.begin(); it != mymap.end(); ++it) {
cout << it->first << " => " << it->second << endl;
fflush(stdout); // Qt环境下需要,否则不会进行控制台输出
}
return a.exec();
}