2

全部,我有以下代码:

在 .h 文件中:

struct Foo
{
   int ma;
   double mb;
   Foo(int a, double b)
   {
        ma = a;
        mb = b;
   }
   Foo()
   {
        ma = 0;
        mb = 0.0;
   }
};

class MyClass
{
public:
    MyClass();
private:
     std::map<std::string,Foo> m_map;
};

In .cpp file:

MyClass::MyClass()
{
    m_map["1"] = Foo( 1, 0.1 );
    m_map["2"] = Foo( 2, 0.2 );
    m_map["3"] = Foo( 3, 0.3 );
}

将 Foo(0, 0) 分配给 m_map["2"] 的最简单方法是什么?

我可以简单地写

m_map["2"] = Foo( 0, 0 );

但在这种情况下,将创建一个 Foo 类型的新变量。

另外,我没有循环,所以不能真正使用迭代器......

谢谢你。

4

5 回答 5

3

你可以简单地写:

m_map["2"];

这是来自cppreference的关于std::map::operator[]

使用 key 作为键和默认构造的映射值将新元素插入容器,并返回对新构造的映射值的引用。

因此,如果您尝试“获取”该值,则将调用您的默认构造函数。

于 2012-12-25T00:12:43.960 回答
2

如果我理解正确,你可以写

m_map["2"].ma = 0;
m_map["2"].mb = 0;

虽然我不明白为什么

m_map["2"] = Foo(0,0); //or just Foo() because of the overloaded constructor

是个问题。

于 2012-12-25T00:11:46.603 回答
1

C++ 使用复制语义,容器保存您放入其中的内容的副本。另请注意,库可以自由复制容器中的对象(例如std::vector在重新分配时),并且假定对象的副本等同于该对象。

如果复制对您来说是一个问题(因为性能或语义),那么解决方案是添加一个间接级别并在映射中放置指向对象或代理的智能指针而不是真实对象本身。

这样,图书馆创建的副本或临时文件的数量将无关紧要。

于 2012-12-25T00:20:07.007 回答
0

我可以简单地写

m_map["2"] = Foo( 0, 0 );

但在这种情况下,将创建一个 Foo 类型的新变量。

不,它会Foo( 0, 0)在地图内部存储中创建实例的副本。

于 2012-12-25T00:08:46.637 回答
0

由于您没有更改 a 值的方法Foo,是的,只需为 a 分配map["2"]一个新对象。旧的将被覆盖 - 因为它无论如何都是原始对象的副本,所以没有区别。反正你的Foo(0,0)寿命很短。

或者,您可以添加一个Foo::SetAB(int a, double b) { ma = a; mb = b; }函数(或两个函数来设置 a 和 b,或者一个将两者都设置为零的 clear 函数,或者这个主题的其他一些变体。然后使用m_map["2"].SetAB(0, 0); - 在这种情况下,两者之间没有太大区别选项,但如果Foo是一些复杂的对象需要花费大量的“努力”来创建(例如,有很多成员、有很多值、要分配的内存、要存储的字符串等),那么拥有一个更改成员变量的函数。

于 2012-12-25T00:14:34.490 回答