什么是复杂对象的“最小框架”(必要的方法)(具有显式的malloced内部数据),我想将其存储在STL容器中,例如<vector>
?
对于我的假设(复杂对象Doit的例子):
#include <vector>
#include <cstring>
using namespace std;
class Doit {
private:
char *a;
public:
Doit(){a=(char*)malloc(10);}
~Doit(){free(a);}
};
int main(){
vector<Doit> v(10);
}
给出
*** glibc detected *** ./a.out: double free or corruption (fasttop): 0x0804b008 ***
Aborted
和valgrind:
malloc/free: 2 allocs, 12 frees, 50 bytes allocated.
更新:
此类对象的最小方法是:(基于sbi答案)
class DoIt{
private:
char *a;
public:
DoIt() { a=new char[10]; }
~DoIt() { delete[] a; }
DoIt(const DoIt& rhs) { a=new char[10]; std::copy(rhs.a,rhs.a+10,a); }
DoIt& operator=(const DoIt& rhs) { DoIt tmp(rhs); swap(tmp); return *this;}
void swap(DoIt& rhs) { std::swap(a,rhs.a); }
};
答案 0 :(得分:10)
请注意Charles完全answered your question。
无论如何,根据Rule of Three,你的类有一个析构函数,也应该有一个复制构造函数和赋值运算符。
我将如何做到这一点:
class Doit {
private:
char *a;
public:
Doit() : a(new char[10]) {}
~Doit() {delete[] a;}
DoIt(const DoIt& rhs) : a(new char[10]) {std::copy(rhs.a,rhs.a+10,a);}
void swap(DoIt& rhs) {std::swap(a,rhs.a);}
DoIt& operator=(DoIt rhs) {swap(rhs); return *this;}
};
答案 1 :(得分:6)
您使用的所有类型都必须是CopyConstructible
和Assignable
。
CopyConstructible
类型, T
表示如果t
是T
或const T
,那么表达式T(t)
必须生成等价物原始T
t
; t。~T()必须有效(可访问的析构函数);并且&t
必须将t
的地址设为[const] T*
。
Assignable
表示对于T
,t
和T
值u
,表达式t = u
必须t
}相当于u
,属于T&
类型。
请注意,所有这些要求都通过简单的内置类型和POD结构来满足。如果在析构函数或构造函数中执行任何非常重要的操作,则必须确保复制构造函数和复制赋值运算符保留等价语义。
答案 2 :(得分:0)
所有vector
要求的是对象是“可赋值的”,这意味着它需要一个copy-constructor,析构函数和赋值运算符,如果你自己不提供它们,它们都是默认生成的。
正如sbi所说,如果您需要其中一种功能,那么您可能需要它们。在您的情况下,您还需要提供复制构造函数和赋值运算符以避免堆损坏。