2013-03-19 218 views
0

我有一个奇怪的问题,我无法理解:C++:使用指向unordered_map的指针,或者只是将它定义为类中的成员变量?

比方说,我有几个成员字段一个class System,其中之一是unordered_map类型的,所以当我在头文件中声明类,我在标题#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类型实例的一部分。

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

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

回答

2

使它不是指针直到你需要使它成为一个指针。

指针充满了用户错误。

例如,你忘了提及你的class System还需要实现

System(const Sysytem&) 

System& operator= (const System&) 

或不良行为就会出现,当您尝试复制你的对象。

5

在像你所描述的情况下,似乎第一个选项更可取。实际上,最有可能的是,无序地图旨在被它所属的类所拥有为。换句话说,它的生命周期不应超出封装类的生命周期,并且封装类负责创建和销毁无序映射。

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

但是,在我看来,像在这里你根本不需要指针。你有一个对象的生命周期完全以包含它的类的生命周期为界。在这种情况下,你应该不使用指针,宁愿把变量声明为:

std::unordered_map<std::string, int> umap; 
0

的区别在于你要如何才能够访问UMAP。指针可以提供更多的灵活性,但它们显然会增加分配的复杂性(堆栈vs堆,析构函数等)。如果你使用一个指向umap的指针,你可以做一些非常复杂的事情,比如用相同的umap制作两个System。最后,除非有令人信服的理由,否则与KISS一起。

0

没有必要将它定义为指针。如果你这样做,你还必须确保实现拷贝构造函数和赋值操作符,或完全禁用它们。

如果没有具体的理由使它成为一个指针(并且你不显示任何),只需将它作为一个正常的成员变量。