简体   繁体   English

C ++:使用指向unordered_map的指针还是仅将其定义为类中此类的成员变量?

[英]C++:using pointer to unordered_map or just defining it as a member variable from this type in a class?

I have a problem which I cannot understand: 我有一个无法理解的问题:

Let's Say I have a class System with several member fields, and one of them is of type unordered_map , so when I declare the class in the header file, I write at the beginning of the header #include <unordered_map> . 假设我有一个包含多个成员字段的class System ,其中一个成员字段的类型为unordered_map ,所以当我在头文件中声明该类时,我将在头文件#include <unordered_map>的开头写入内容。

Now, I have two ways of declaring this field: 现在,我有两种声明该字段的方法:

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

Now in the constructor of the class, if I choose the first option, there is no need to initialize that field in the initializer list since the constructor of class System will call the default constructor for the field umap as part of constructing an instance of type class System . 现在在类的构造函数中,如果我选择第一个选项,则无需初始化初始化程序列表中的该字段,因为class System的构造函数将调用umap的默认构造函数作为构造类型实例的一部分class System

If I choose the second option, I should initialize the field p_umap in the constructor (in the initialize list) with the operator new and in the destructor, to delete this dynamic allocation. 如果选择第二个选项,则应使用构造函数new和析构函数在构造函数中(在初始化列表中)初始化字段p_umap ,以删除此动态分配。

What is the difference between these two options? 这两个选项有什么区别? If you have a class that one of it's fields is of type unordered_map , how do you declare this field? 如果您有一个其中某个字段的类型为unordered_map的类,那么如何声明此字段? As a pointer or as a variable of type unordered_map ? 作为指针还是unordered_map类型的变量?

In a situation like the one you are describing, it seems like the first option is preferable. 在您所描述的情况下,似乎第一个选项更可取。 Most likely, in fact, the unordered map is intended to be owned by the class it is a data member of. 实际上,最有可能的是,无序映射打算由属于它的数据成员的类拥有 In other words, its lifetime should not be extended beyond the lifetime of the encapsulating class, and the encapsulating class has the responsibility of creating and destroying the unordered map. 换句话说,其生存期不应超过封装类的生存期,并且封装类负责创建和销毁无序映射。

While with option 1 all this work is done automatically, with option 2 you would have to take care of it manually (and take care of correct copy-construction, copy-assignment, exception-safety, lack of memory leaks, and so on). 使用选项1时,所有这些工作都是自动完成的,而使用选项2时,您将必须手动进行处理(并注意正确的复制构造,复制分配,异常安全性,内存泄漏等)。 。 Surely you could use smart pointers (eg std::unique_ptr<> ) to encapsulate this responsibility into a wrapper that would take care of deleting the wrapped object when the smart pointer itself goes out of scope (this idiom is called RAII, which is an acronym for Resource Acquisition Is Initialization ). 当然,您可以使用智能指针(例如std::unique_ptr<> )将此职责封装到包装器中,当智能指针本身超出范围时,它将负责删除包装的对象(此惯用法称为RAII,这是一个资源获取的首字母缩写是初始化 )。

However, it seems to me like you do not really need a pointer at all here. 但是,在我看来, 似乎根本不需要指针 You have an object whose lifetime is completely bounded by the lifetime of the class that contains it. 您有一个对象,其生存期完全由包含该对象的类的生存期限制。 In these situations, you should just not use pointers and prefer declaring the variable as: 在这些情况下,您不应仅使用指针,而应将变量声明为:

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

Make it not a pointer until you need to make it a pointer. 让它不是一个指针 ,直到你需要它的指针。

Pointers are rife with user error. 指针到处都是用户错误。

For example, you forgot to mention that your class System would also need to implement 例如,您忘记提及您的class System也将需要实现

System( const Sysytem& )

and

System& operator= ( const System& )

or Bad Behavior will arise when you try to copy your object. 或尝试复制对象时,将出现“不良行为”。

The difference is in how you want to be able to access umap. 不同之处在于您希望如何访问umap。 Pointers can allow for a bit more flexibility, but they obviously add complexity in terms of allocation (stack vs heap, destructors and such). 指针可以提供更多的灵活性,但显然会增加分配方面的复杂性(堆栈与堆,析构函数等)。 If you use a pointer to umap, you can do some pretty convoluted stuff such as making two System's with the same umap. 如果使用指向umap的指针,则可以执行一些复杂的工作,例如使用相同的umap制作两个System。 In the end though, go with KISS unless there's a compelling reason not to. 最后,除非有令人信服的理由,否则请选择KISS。

There is no need to define it as pointer. 无需将其定义为指针。 If you do it, you must also make sure to implement copy constructor and assignment operator, or disable them completely. 如果这样做,还必须确保实现复制构造函数和赋值运算符,或者完全禁用它们。

If there is no specific reason to make it a pointer (and you don't show any) just make it a normal member variable. 如果没有特定的理由使其成为指针(并且您没有显示任何指针),只需使其成为普通成员变量即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM