英文:
Is there a std container, other than std::vector, which does not copy and destroy elements which are classes?
问题
-
是否有一种std容器可以使用,不会创建、存储和销毁要添加的元素的副本?
-
对于每个涉及的类是否使用深拷贝构造函数会解决问题?
-
标准的“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.
-
Is there a std container I might employ which does not make, store and destroy copies of the elements being added?
-
Would a deep copy constructor for each class in question solve the problem?
-
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
-
您有两个问题。
这是一个问题。如果您不希望您的类具有深度复制语义,那么没问题,它们不必... 但是然后应该安全地进行复制(不拥有和销毁它们引用的资源),或者至少应该使它们无法复制。
或者,正如您所说,使它们具有深度复制能力(尽管这可能不是您想要的)。
-
您不必要地复制。
push_back
不必复制。 有push_back(T&&)
。因此,考虑将对象
std::move
到向量中。如果在WindowsWindow
中有正确实现的移动构造函数和移动赋值运算符,这将非常便宜。您还可以直接使用
emplace
构造元素。
这两者都不是 std::vector
的错,创建一个不执行此操作的替代向量类型只是一种绕过您的类的破碎复制/移动语义的奇怪方法。
tl;dr: 为您的类正确实现复制和移动语义。
英文:
You have two problems here.
-
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).
-
You're copying unnecessarily.
push_back
doesn't have to copy. There is apush_back(T&&)
.So, consider
std::move
ing your objects into the vector instead. With a properly implemented move constructor and move assignment operator inWindowsWindow
, 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论