0

我有一个我无法理解的问题:

假设我有一个class System有几个成员字段,其中一个是 type unordered_map,所以当我在头文件中声明类时,我会在 header 的开头写#include <unordered_map>

现在,我有两种声明这个字段的方法:

1.std::unordered_map<std::string,int> umap;
2.std::unordered_map<std::string,int>* p_umap;

现在在类的构造函数中,如果我选择第一个选项,则无需在初始化列表中初始化该字段,因为构造函数class System将调用该字段的默认构造函数umap作为构造类型实例的一部分class System

如果我选择第二个选项,我应该p_umap在构造函数(在初始化列表中)使用运算符 new 和在析构函数中初始化字段,以删除此动态分配。

这两个选项有什么区别?如果你有一个类,它的一个字段是 type unordered_map,你如何声明这个字段?作为指针还是作为类型的变量unordered_map

4

4 回答 4

5

在您所描述的情况下,似乎第一个选项更可取。事实上,最有可能的是,无序映射旨在由它作为数据成员的类拥有。换句话说,它的生命周期不应该超过封装类的生命周期,封装类有创建和销毁无序映射的责任。

虽然使用选项 1,所有这些工作都是自动完成的,但使用选项 2,您必须手动处理它(并注意正确的复制构造、复制分配、异常安全、没有内存泄漏等) . 当然,您可以使用智能指针(例如std::unique_ptr<>)将此责任封装到一个包装器中,当智能指针本身超出范围时,该包装器将负责删除包装的对象(这个习惯用法称为 RAII,它是Resource Acquisition Is Initialization的首字母缩写词)。

但是,在我看来,您在这里根本不需要指针。您有一个对象,其生命周期完全受包含它的类的生命周期限制。在这些情况下,您不应该使用指针,而是更喜欢将变量声明为:

std::unordered_map<std::string, int> umap;
于 2013-03-19T19:43:23.777 回答
2

在您需要使其成为指针之前,使其不是指针。

指针充斥着用户错误。

例如,您忘记提及您class System还需要实施

System( const Sysytem& )

System& operator= ( const System& )

或当您尝试复制对象时会出现不良行为。

于 2013-03-19T19:42:51.257 回答
0

不同之处在于您希望如何访问 umap。指针可以提供更多的灵活性,但它们显然增加了分配方面的复杂性(堆栈与堆、析构函数等)。如果您使用指向 umap 的指针,您可以做一些非常复杂的事情,例如使用相同的 umap 制作两个系统。最后,除非有令人信服的理由不这样做,否则请选择 KISS。

于 2013-03-19T19:43:43.400 回答
0

无需将其定义为指针。如果这样做,还必须确保实现复制构造函数和赋值运算符,或者完全禁用它们。

如果没有特定理由将其设为指针(并且您没有显示任何指针),只需将其设为普通成员变量即可。

于 2013-03-19T19:44:14.650 回答