正确使用std::map作为类成员

6

过去我总是创建这样的地图:

class TestClass
{
    private:
        std::map<int,int> *mapA;
};

TestClass::TestClass
{
    mapA = new std::map<int,int>();
}

TestClass::~TestClass
{
    mapA->clear(); // not necessary
    delete mapA;
}

我在Stackoverflow上看到很多人都建议尽可能避免使用指针

目前,我想创建一个不需要指针和new操作的地图(无需手动删除对象,且存在内存泄漏的风险更小)!

class TestClass
{
    public:
        TestClass() : mapA() // this is also needed?
        {};
    private:
        std::map<int,int> mapA;
};

是否需要采取进一步的措施来正确创建地图?

感谢任何帮助和/或澄清!


1
我刚注意到你在原始析构函数中添加了mapA->clear()。这是不必要的 - 在析构期间,map会自行清除。 - zennehoy
无论哪种情况,您都不需要调用 map::clear - Ajay
2个回答

9

不需要,而且你不需要在构造函数中显式初始化它。


1
我总是感到惊讶,尽管没有指针的代码比有指针的代码简单得多,但新手们似乎总是选择指针版本。 - john
1
@john 或许并非如此;只是那些使用指针的人会遇到麻烦,我们才会注意到他们。 - Gorpik
@john 经常有人从Java转来,由于在Java中需要重新创建所有内容,所以他们在C++中也会这样做。 - Andre Kostur
Andre,John:当然还有来自C语言的指针地狱。@Gorpik::-)) - Sz.
为什么我们不需要在成员初始化列表中初始化映射? - Tesla123
@Tesla123 因为类成员隐式地默认构造。 - zennehoy

4

正如zennehoy所说,不需要在TestClass构造函数中初始化map。让我注意一下这两种实现之间的区别:

在第一种实现中,TestClass当前写法下是不能被复制的,因为动态分配的map的原始指针会被复制,从而产生不良影响:

TestClass *A = new TestClass;      // A has a map
TestClass *B = new TestClass(A);   // B shares the map with A!

delete A; // this deletes A's map (in destructor)
delete B; // this deletes A's map again! wrong

在您的第二个实现中,这种情况不会发生,因为整个映射而不仅仅是它的地址被完全复制。
为解决第一个实现中的问题,您应该使用共享指针,或通过实现operator=和复制构造函数自己完成工作。或者,如果您想在复制的实例之间真正共享地图,则应实现引用计数机制。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接