哪个更好:存储对象与存储指针? [重复]

时间:2022-01-27 16:32:22

This question already has an answer here:

这个问题在这里已有答案:

I want to store elements (let's call it E), but I don't know that I should store them as objects or as pointers pointing to the dynamically allocated objects.

我想存储元素(让我们称之为E),但我不知道我应该将它们存储为对象或指向动态分配对象的指针。

(A,B,C,etc. objects store the reference of the wanted E)

(A,B,C等对象存储所需E的引用)

version A:

E e;
store.Add(e); //This time the store contains objects.

In this version the element will be copied to the store, but it's easier to handle. (The objects will be destroyed when the parent object is destroyed)

在这个版本中,元素将被复制到商店,但它更容易处理。 (销毁父对象时将销毁对象)

version B:

E* e = new E();
store.Add(*e); //This time the store contains references.
/*I chose references instead of pointers, 
so I have to use pointers only at allocating and deallocating.*/

In this version there is no copy constr. but I have to delete the objects in the parent object's destructor.

在这个版本中没有复制constr。但我必须删除父对象的析构函数中的对象。

Which is better and why? Which can cause more mistakes and which is more efficient?

哪个更好?为什么?哪个会导致更多错误,哪个更有效?

2 个解决方案

#1


2  

It depends on how you're using your store. Storing objects means you will copy them when calling Add, and also when copying the store (among other circumstances): that could have a cost, and can lead to unwanted behaviours.

这取决于你如何使用你的商店。存储对象意味着您将在调用Add时复制它们,并且在复制存储时(以及其他情况):这可能会产生成本,并可能导致不需要的行为。

Pointers may be a good alternative, but you should then prefer managed pointers, like std::unique_ptr, so you won't have to handle deletion.

指针可能是一个很好的选择,但你应该更喜欢托管指针,比如std :: unique_ptr,所以你不必处理删除。

version C:

auto e = std::unique_ptr<E>(new E());
store.Add(e); //This time the store contains managed pointers.

You can also use std::make_unique if you have C++14 available.

如果您有C ++ 14可用,也可以使用std :: make_unique。

version C bis:

版本C之二:

auto e = std::make_unique<E>();
store.Add(e); //This time the store contains managed pointers.

Another option if you need to share the pointed objects can be to use std::shared_ptr, but use it only if need it.

如果需要共享指向对象,另一个选项可以是使用std :: shared_ptr,但仅在需要时才使用它。

version D:

auto e = std::make_shared<E>();
store.Add(e); //This time the store contains shared managed pointers.

#2


2  

With c++11 an onward you can also just construct them directly inside the container:

使用c ++ 11,你也可以直接在容器中构建它们:

std::vector<Widget> widgets;
widgets.emplace_back(/*Parameters to construct a widget*/);

Which is better and why?

哪个更好?为什么?

That depends on your application. If the container is supposed to own the objects, and they aren't too expensive to copy, value semantics are easier. If they are expansive to copy, but easily movable, the standard containers will move them instead (you of course have to supply the move constructors).

这取决于您的申请。如果容器应该拥有对象,并且复制起来不太昂贵,那么值语义会更容易。如果它们很容易复制,但很容易移动,标准容器会移动它们(你当然必须提供移动构造器)。

You can also have the best of both worlds, by storing smart pointers instead. That way you'd get polymorphism if that's a requirement.

通过存储智能指针,您还可以充分利用这两个方面。这样,如果这是一个要求,你会得到多态性。

std::vector<std::unique_ptr<Widget>> widgets;
widgets.push_back(std::make_unique<Widget>(/*Parameters to construct a widget*/));

Which can cause more mistakes and which is more efficient?

哪个会导致更多错误,哪个更有效?

The first question depends entirely on your skill as a programmer, and the second cannot be answered with a blanket statement. Programs need to be bench-marked and profiled for efficiency.

第一个问题完全取决于你作为程序员的技能,而第二个问题不能用一揽子声明来回答。程序需要进行基准标记和分析以提高效率。

#1


2  

It depends on how you're using your store. Storing objects means you will copy them when calling Add, and also when copying the store (among other circumstances): that could have a cost, and can lead to unwanted behaviours.

这取决于你如何使用你的商店。存储对象意味着您将在调用Add时复制它们,并且在复制存储时(以及其他情况):这可能会产生成本,并可能导致不需要的行为。

Pointers may be a good alternative, but you should then prefer managed pointers, like std::unique_ptr, so you won't have to handle deletion.

指针可能是一个很好的选择,但你应该更喜欢托管指针,比如std :: unique_ptr,所以你不必处理删除。

version C:

auto e = std::unique_ptr<E>(new E());
store.Add(e); //This time the store contains managed pointers.

You can also use std::make_unique if you have C++14 available.

如果您有C ++ 14可用,也可以使用std :: make_unique。

version C bis:

版本C之二:

auto e = std::make_unique<E>();
store.Add(e); //This time the store contains managed pointers.

Another option if you need to share the pointed objects can be to use std::shared_ptr, but use it only if need it.

如果需要共享指向对象,另一个选项可以是使用std :: shared_ptr,但仅在需要时才使用它。

version D:

auto e = std::make_shared<E>();
store.Add(e); //This time the store contains shared managed pointers.

#2


2  

With c++11 an onward you can also just construct them directly inside the container:

使用c ++ 11,你也可以直接在容器中构建它们:

std::vector<Widget> widgets;
widgets.emplace_back(/*Parameters to construct a widget*/);

Which is better and why?

哪个更好?为什么?

That depends on your application. If the container is supposed to own the objects, and they aren't too expensive to copy, value semantics are easier. If they are expansive to copy, but easily movable, the standard containers will move them instead (you of course have to supply the move constructors).

这取决于您的申请。如果容器应该拥有对象,并且复制起来不太昂贵,那么值语义会更容易。如果它们很容易复制,但很容易移动,标准容器会移动它们(你当然必须提供移动构造器)。

You can also have the best of both worlds, by storing smart pointers instead. That way you'd get polymorphism if that's a requirement.

通过存储智能指针,您还可以充分利用这两个方面。这样,如果这是一个要求,你会得到多态性。

std::vector<std::unique_ptr<Widget>> widgets;
widgets.push_back(std::make_unique<Widget>(/*Parameters to construct a widget*/));

Which can cause more mistakes and which is more efficient?

哪个会导致更多错误,哪个更有效?

The first question depends entirely on your skill as a programmer, and the second cannot be answered with a blanket statement. Programs need to be bench-marked and profiled for efficiency.

第一个问题完全取决于你作为程序员的技能,而第二个问题不能用一揽子声明来回答。程序需要进行基准标记和分析以提高效率。