提问人:osgx 提问时间:3/23/2010 最后编辑:Communityosgx 更新时间:3/2/2018 访问量:1673
在 STL 向量中存储对象 - 最少的方法集
Storing objects in STL vector - minimal set of methods
问:
什么是复杂对象(具有显式分配的内部数据)的“最小框架”(必要方法),我想将其存储在 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
在瓦尔格林德:
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); }
};
答:
10赞
sbi
3/23/2010
#1
请注意,查尔斯已经完美地回答了您的问题。
无论如何,根据三法则,具有析构函数的类也应该具有复制构造函数和赋值运算符。
这是我的做法:
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;}
};
评论
0赞
osgx
3/23/2010
你能为我的案例提供复制构造函数和赋值运算符的代码吗?
0赞
AshleysBrain
3/24/2010
我认为您在 Doit() 构造函数之后缺少一个冒号
0赞
Konrad
3/24/2010
@AshleysBrain,nope Doit() a(new char[10]) {} 对我来说似乎是完全合法的。如果没有 {},那么我会同意你的看法。
0赞
sbi
3/24/2010
@Konrad:当然错过了.我解决了这个问题。Doit() a(new char[10]) {}
:
1赞
Glen
3/24/2010
@osgx,没有人会因为任何事情而责怪任何人。像这样的澄清旨在帮助提出问题的人,在这种情况下是您,获得最佳答案。
0赞
Peter Alexander
3/23/2010
#2
所有要求是对象是“可赋值的”,这意味着它需要一个复制构造函数、析构函数和赋值运算符,如果你不自己提供它们,它们都是默认生成的。vector
正如 sbi 所说,如果你需要这些功能之一,那么你可能需要它们。在您的情况下,您还需要提供复制构造函数和赋值运算符,以避免堆损坏。
6赞
CB Bailey
3/23/2010
#3
您使用的所有类型都必须是 和 。CopyConstructible
Assignable
CopyConstructible
因为类型意味着如果 is a 或 a,则表达式必须产生与原始表达式等价的表达式;t.~T() 必须有效(可访问的析构函数);并且必须提供 的地址作为 .T
t
T
const T
T(t)
T
t
&t
t
[const] T*
Assignable
表示对于 和 值,表达式必须等价于 和 的类型。T
t
T
u
t = u
t
u
T&
请注意,所有这些要求都可以通过简单的内置类型和 POD 结构来满足。如果在析构函数或构造函数中执行任何非平凡的操作,则必须确保复制构造函数和复制赋值运算符保留等价语义。
评论
1赞
osgx
10/11/2012
您能否提供以下表格的链接:不同的 STL 容器(vector/map/priority_queue/hash/etc)需要哪些概念(Assignable、CopyConstructible、其他?)才能在其中存储非平凡的对象。
2赞
CB Bailey
10/11/2012
它们不是“概念”,而是类型要求,您可以在标准中找到它们。
评论
std::vector