【发布时间】:2018-11-11 13:33:10
【问题描述】:
举个例子:
#include <iostream>
#include <stdio.h>
#include <vector>
using namespace std;
class Foo{
public:
Foo(){
cout << "Constructing the default way..." << endl;
this->num = (int*)malloc(sizeof(int));
}
Foo(int a){
cout << "Using a custom constructor..." << endl;
this->num = (int*)malloc(sizeof(int) * a);
}
~Foo(){
cout << "Destructing..." << endl;
free((void*)num);
}
int* num;
};
int main()
{
vector<Foo> objects(5);
for(Foo& v : objects) printf("%x0x\n", v.num);
cout << "\n---------------\n";
cout << "END OF PROGRAM!\n";
cout << "---------------\n\n";
return 0;
}
通过传递对象的初始计数来创建向量,从而单独创建每个对象,因此,所有对象的num 位于不同的地址,并且它们的析构函数在程序结束时被调用。
但是,如果我想通过给它一个自定义构造函数来创建向量,比如vector<Foo> objects(5, Foo(5)); (这只是我的猜测),一个临时对象被构造,然后复制到数组中的每个对象.实际上,这使得向量中的每个对象都有它们的num 指针指向相同的内存。另外,当初始化完成时,内存会被释放,然后每个对象都变得无用。
如何在不将自定义构造函数变成新的Init(int) 函数并在向量中的每个对象上运行它的情况下解决这个问题? (当然是把malloc改成realloc)。
【问题讨论】:
-
你可能想要std::fill。
-
这个问题展示了你想如何解决一个问题。问题的问题是您没有告诉我们您要解决的实际问题,您只是问我们如何解决这个未知问题的解决方案。这是一个非常典型的XY problem。请尝试向我们询问您想要解决的真正问题,告诉我们您的解决方案(您拥有的),也许我们将能够以更好的方式帮助您解决真正的问题。如果没有,那么我们将为您提供解决方案。
-
另外,在 C++ 中永远不要使用
malloc和free,甚至对于像int数组这样的原始类型也不行。始终以std::vector开头。你需要了解the rules of three/five/zero,使用std::vector,你可以遵循我推荐的零规则。 -
malloc/free绝不应该在 C++ 程序中使用。他们不调用构造函数/析构函数。改用new/delete- 好吧,不是真的;请使用容器和/或智能指针而不是手动内存管理。 -
这只是我的猜测 -- 无需猜测。通过打开
#include <vector>标头,您可以轻松获得编译器的std::vector实现。或者简单地调试并逐步查看该构造函数是如何工作的。无论如何,std::vector类很可能使用placement-new,而不是您认为的天真的“创建临时副本”。编写std::vector实现的程序员是世界上最优秀的专业人士——他们对优化这些事情的了解远远超过普通 C++ 程序员。