我无法将foo
对象添加到地图myFoos
中,直到我发现this answer表示需要默认构造函数。
将对象添加到地图时,我希望将其简单地复制并放置到位,然而,真正发生的是默认构造,赋值和副本。
有人可以解释这种行为吗?
#include <map>
using namespace::std;
class Foo {
public:
Foo() { }; // Default
Foo(int id) : _id(id) { }; // Main
Foo(const Foo& other) { }; // Copy
Foo operator= (const Foo& other) { _id = other._id; return *this; } // Assign
int getID() { return _id; }
private:
int _id;
};
int main()
{
map<int,Foo> myFoos;
Foo foo(123); // Main
myFoos[123] = foo; // Default, Assign, Copy
}
修改 我最初没有在赋值运算符的函数体中发生任务,并且一些答案正确地指出了这一点。我相应地修改了代码。
答案 0 :(得分:4)
在完成任何作业和副本之前,代码myFoos[123]
需要创建一个Foo
,以便在地图中插入密钥123
。然后将该值复制或移动到map
中,然后返回给您进行进一步操作。
索引运算符返回对映射中元素的引用,如果它不存在,则会创建它并为您插入。如果它已经存在,它只返回对已经存在的那个的引用。
T& operator[]( Key&& key );
返回对映射到等效于
key
的键的值的引用,如果此类键尚不存在则执行插入。如果执行插入,则映射值是值初始化的(默认为类类型构造,否则为零初始化),并返回对它的引用。
int id = myFoos[123].getID(); // returns 0 instead of 123
这里的0
是因为该类尚未完全实现(默认和复制构造函数以及赋值运算符),因此id
在默认构造函数中初始化(在本例中为0)
答案 1 :(得分:3)
operator[]
使用默认构造函数初始化指定键的元素,并返回对它的引用。
您的分配操作员省略(有意或无意)分配
_id = other._id
。
因此,在
myFoos[123] = foo;
默认_id=0
未被foo._id
替换。