我有以下问题:
void add(){
cRow Row();
Row.add("Column", "Value");
std::vector<cRow> mRows;
mRows.push_back(Row);
}
cRow::cRow(): mCol(NULL), mVal(NULL) {
}
cRow::add(const char* Col, const char* Val){
mCol = strdup(Col);
mVal = strdup(Val);
}
cRow::~cRow(){
free(mCol);
free(mVal);
}
将局部变量Row添加到向量后,将为该行调用析构函数并释放字符串。
显然,现在也释放了向量中存储行的字符串的指针。离开本地范围后对行的任何访问都将导致段错误。
行的转储看起来像这样的2次调用:
| (null) | (null) |
-----------------------------------------------------
| (null)| (null) |
| LastContainerUpdatePropagation| 1307967498 |
------------------------ END ------------------------
3次电话后:
| (null) | (null) |
-----------------------------------------------------
| (null)| (null) |
| (null)| (null) |
| LastSystemUpdatePropagation| 1307967498 |
------------------------ END ------------------------
并且在完全离开范围而不添加新行之后,每一行都被释放。
所以,现在我的问题:std:vector如何复制对象?我需要做些什么来保持指向字符串的指针或将它们复制到另一个空间?
非常感谢!
答案 0 :(得分:9)
std::vector
使用copy constructor复制对象。由于您尚未定义复制构造函数,因此它将使用implicit C++ copy constructor,它只是递归复制所有成员;这还不够,因为你手动管理内存。
您需要定义自己的复制构造函数,或使用std::string
之类的东西,如果复制的话,它会做正确的事情。
作为一个好的做法,任何具有非平凡析构函数的类都应该有一个复制构造函数和复制赋值运算符,正是出于这个原因(这被称为rule of three)。如果复制构造函数没有意义(例如,对于像ostream
这样的东西),它应该是私有的,以防止意外复制。
答案 1 :(得分:2)
std::vector
使用复制构造函数初始化其元素。如果您没有明确写入,编译器会提供一个,但在进行内存管理时,您需要:
cRow
类中所需的那些内容(请注意,您仍需要提供RAII容器的相应复制构造函数,复制赋值运算符和析构函数。)const char*
,它可以替换为std::string
,它将处理内存管理。注意:只有方法#3可以避免编写三个功能的自定义版本。