2016-11-29 68 views
-3

我想存储元素(让我们称之为E),但我不知道应该将它们存储为对象还是指向指向动态分配对象的指针。哪个更好:存储对象vs存储指针?

(A,B,C等对象存储有用E的参考)

版本答:

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

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

版本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.*/ 

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

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

+1

你有C++ 11? – Danh

+1

由于这个问题是关于*商店*,所以标准容器中的[object slicing](http://stackoverflow.com/q/274626/3545273)也应该被注意到。 –

回答

2

用C++ 11的起你也可以只构建它们直接在容器内:

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

哪个更好,为什么?

这取决于您的应用程序。如果容器应该拥有这些对象,并且它们不太复制,那么值语义更容易。如果他们广泛地复制,但容易移动,标准容器移动它们(您当然必须提供移动构造函数)。

您也可以通过存储智能指针来获得两全其美的效果。这样你就会得到多态,如果这是一个要求。

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

这可能会导致更多的错误,这是更有效?

的第一个问题完全取决于你的技能,作为一个程序员,第二不能用毯子声明来回答。程序需要进行基准测试并进行效率分析。

2

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

指针可能是一个很好的选择,但您应该更喜欢托管指针,如std::unique_ptr,因此您不必处理删除操作。

版本C:

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

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

C版之二:

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

,如果你需要共享的尖锐物体可以使用std::shared_ptr,但只使用它,如果需要的另一种选择。

版本d:

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