除了 `std::vector` 之外,是否有一种不复制和销毁类元素的标准容器?

huangapple go评论78阅读模式
英文:

Is there a std container, other than std::vector, which does not copy and destroy elements which are classes?

问题

  1. 是否有一种std容器可以使用,不会创建、存储和销毁要添加的元素的副本?

  2. 对于每个涉及的类是否使用深拷贝构造函数会解决问题?

  3. 标准的“C”风格数组是否可行?

我已经养成了在非类对象的情况下使用std::vector来替代“C”风格数组的习惯,所以这对我来说都是一种新的经验。

英文:

I know that std::vector::push_back() puts a copy in the vector. I am looking for a way or a std container which does not destroy the class members of an instantiated class.

I have a class, WindowsWindow with members,

private:
	GLFWwindow* m_pGLFWwindow = nullptr;
	EventHandler m_eventHandler;
	VertexArrayObject m_VAO;
	bool m_windowAvailable = true;
	std::uint8_t m_windowNumber = 0;
	std::string m_windowTitle = "";

Two of those members, viz., EventHandler, VertexArrayObject, are classes which themselves contain members which are classes.

When I std::vector::push_back() an instantiation of a WindowsWindow object into or onto a std::vector, all of the class member variables are destroyed since a copy is being made and then destroyed. Maybe the answer is to make a deep copy constructor for each class, which I have not tried.

I also tried,

std::vector<std::shared_ptr<WindowsWindow>> WindowsWindowVector;
std::shared_ptr<WindowsWindow> pmainWindow = std::make_shared<WindowsWindow>("Main Window", false);
...
WindowsWindowVector.push_back(pmainWindow);

Which fared no better.

  1. Is there a std container I might employ which does not make, store and destroy copies of the elements being added?

  2. Would a deep copy constructor for each class in question solve the problem?

  3. Would a standard "C" style array work?

I have gotten into the habit of using std::vector in place of the "C" style array for non-class objects so this is all a new experience.

答案1

得分: 4

  1. 您有两个问题。

    这是一个问题。如果您不希望您的类具有深度复制语义,那么没问题,它们不必... 但是然后应该安全地进行复制(不拥有和销毁它们引用的资源),或者至少应该使它们无法复制。

    或者,正如您所说,使它们具有深度复制能力(尽管这可能不是您想要的)。

  2. 您不必要地复制。

    push_back 不必复制。 push_back(T&&)

    因此,考虑将对象 std::move 到向量中。如果在 WindowsWindow 中有正确实现的移动构造函数和移动赋值运算符,这将非常便宜。

    您还可以直接使用 emplace 构造元素。

这两者都不是 std::vector 的错,创建一个不执行此操作的替代向量类型只是一种绕过您的类的破碎复制/移动语义的奇怪方法。


tl;dr: 为您的类正确实现复制和移动语义。

英文:

You have two problems here.

  1. Your class is not copy-safe.

    This is a problem anyway. If you do not want your classes to have deep copy semantics, then that's fine they don't have to… but then it should be made safe to copy (by not owning & destroying the resources they refer to), or at least should be made non-copyable.

    Alternatively, as you say, make them deep-copyable (though this may not be what you want).

  2. You're copying unnecessarily.

    push_back doesn't have to copy. There is a push_back(T&&).

    So, consider std::moveing your objects into the vector instead. With a properly implemented move constructor and move assignment operator in WindowsWindow, this will be very cheap.

    You could also emplace-construct the element directly.

Neither of these is std::vector's fault, and creating a replacement vector type that does not do this would only be a strange hack around your class's broken copy/move semantics.


tl;dr: properly implement copy and move semantics for your class.

huangapple
  • 本文由 发表于 2020年1月3日 22:21:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/59580179.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定