需要帮助理解使用C ++ map作为关联数组

时间:2009-11-17 21:17:21

标签: c++ map

我正在通过Josuttis的“使用地图作为关联数组”(来自The C++ Standard Library - A Tutorial and Reference, 2nd Edition)并在Stack Overflow上遇到Using a std::map as an associative array。现在我对插入地图时调用的构造函数有了更多的疑问。

这是我的示例程序(不使用最佳编码方法;请原谅我):

class C
{
public:

   string s;

   C() { cout << "default " << endl;}

   C(const string& p) : s(p)
   { cout << "one param" << endl;}

   C(const C& obj)
   {
       if (this != &obj)
       {
         s = obj.s;
       }
       cout << "copy constr" << endl;
   }

   C& operator  = (const C& obj)
   {
       if (this != &obj)
       {
             s = obj.s;
       }
      cout << "copy initializer" << endl;
      return *this;
   }
};

int main()
{
    map<int,C> map1;
    C obj("test");

    cout << "Inserting using index" << endl;
    map1[1] = obj;

    cout << "Inserting using insert / pair" << endl;
    map1.insert(make_pair(2,obj));
}

该程序的输出是:

one param
Inserting using index
default
copy constr
copy constr
copy initializer
Inserting using insert / pair
copy constr
copy constr
copy constr
copy constr

我假设按索引初始化地图应调用默认构造函数,然后调用赋值运算符。

但执行map1[1] = obj会创建以下输出;

Inserting using index
default
copy constr
copy constr
copy initializer

有人可以帮助我更好地理解初始化吗?

4 个答案:

答案 0 :(得分:8)

如果你读了std :: map的规范,那就说operator []相当于(在这种情况下)

(*((this->insert(make_pair(1,C()))).first)).second

所以这解释了你看到的所有构造函数调用。首先,它调用默认构造函数C()。然后它调用make_pair,它复制C对象。然后它调用insert,它生成你刚刚创建的pair对象的副本,再次调用C拷贝构造函数。最后,它调用赋值运算符将插入的对象设置为您指定的对象。

答案 1 :(得分:2)

不知道。 但这很有趣:

#include <string>
#include <map>
#include <iostream>
using namespace std;

class C
{
    public:
        string s;
        C()
        {
            cout << "default " << endl;
        }
        C(const string& p)
        : s(p)
        {
            cout << "one param(" << s << ")" << endl;
        }
        C(const C& obj)
            :s(obj.s)
        {
           cout << "copy constr(" << s << ")" <<endl;
        }
        C& operator  = (const C& obj)
        {
            cout << "copy initializer\t" <<;

            C copy(obj);
            std::swap(s,copy.s);

            return *this;
        }
};

int main()
{
    map<int,C> map1;
    cout << "Inserting using index" << endl;
    map1[1] = C("Plop");
}

看起来默认创建并复制了它 然后,外部的一旦被放置到位就会被激活。

Inserting using index
default
copy constr()
copy constr()
one param(Plop)
copy initializer      copy constr(Plop)

答案 2 :(得分:0)

如果您只是执行map[1];会怎样?这可能涉及内部副本,具体取决于标准库使用的map的实现。

答案 3 :(得分:0)

实际上map1[1] = obj将首先创建pair