用C ++声明向量和集合

时间:2013-03-06 01:27:24

标签: c++ pointers vector set

这是我第一次使用C ++中的STL容器,在看到Google中的不同示例时,我发现了一些关于向量和集合声明的方法。

如果您有一个A类并且想要将这些元素存储在向量中,则使用指向A对象的指针(如下所示)。对于集合,您可以使用声明中的实际对象。我想知道是否有这样做的特殊原因,或者只是在我看到的例子中发生。

vector<*A> cont1;
set<A> cont2;

7 个答案:

答案 0 :(得分:3)

在大多数情况下,你最终会使用具有自动存储持续时间的对象容器而不是指针/智能指针,因为这样的容器会为你处理丑陋的内存管理。

简单std::vector<A>在大多数情况下应该足够了。那些非常罕见的情况需要使用std::vector<A*>。这种情况的一个例子可能是在使用此容器的元素时需要实现运行时多态性。另一个示例可能是使用指针,因为在复制A时可能会出现性能问题。另一个原因可能是避免对象切片

好的做法是始终使用对象容器,除非你有充分的理由使用指针容器。即使您需要保持指针,也请使用智能指针

相关问题:
How to avoid memory leaks when using a vector of pointers to dynamically allocated objects in C++?
C++: Vector of objects vs. vector of pointers to new objects?

答案 1 :(得分:2)

我不知道这是常见做法。

但是,这样做的一个可能原因是,当vector调整大小时,包含的对象可以在内存中移动。如果包含的对象将this指针指向其他某个对象,则该指针在resize之后可能无效。通过存储指针并自己管理内存,您的对象不会受此影响。

使用set,您将不会观察到相同的行为,因为集合往往被实现为树。请注意:我不认为C ++标准库对此有任何保证......

如果作者试图利用set来利用它,那么他们就会滥用封装规则。如果没有,那么您提供的两个示例可能不相关。将指针(或不指针)存储在容器中还有很多其他原因,您可以自由选择。

答案 2 :(得分:1)

这只是你遇到过的例子。您可以存储从对象本身,指针到向量中的函数指针的任何内容。您还可以在矢量中存储其他矢量以定义多维向量:

// define 4x4 vector
vector< vector<int> > vec(4, vector<int>(4));

vec[i][j] = a;     // write
int b = vec[i][j]; // read

答案 3 :(得分:1)

vector<A*> cont1;
cont1.push_back( new A( whatever ) );
vector<A> cont2;
cont2.push_back( A( whatever ) );

这取决于您拥有的用例。你想存储对象或指针吗?

请注意,第一个示例需要您手动delete每个对象,而第二个示例将为您处理删除。尽可能使用秒,除非你知道你在做什么。它还使分配(等)安全。

答案 4 :(得分:1)

这取决于您要存储的内容。

std::vector<A*> myVector;

...将创建一个存储指向A类型的指针的向量。

std::set<A> mySet;

...将创建一个存储A类型实际实例的集合。

您可以轻松地将实际实例存储在矢量中:

std::vector<A> myVector;

或集合中的指针:

std::set<A*> mySet;

答案 5 :(得分:1)

集合和向量之间的真正区别在于集合包含所有唯一元素,并且其操作具有不同的运行时。它们完全不相同!

区别的原因是您可以拥有两个相同的动态分配对象,但这些对象存储在不同的位置。如果你这样做:

A a,b;
std::vector<A> myVector;
myVector.push_back(a);
myVector.push_back(b);

然后myVector将包含两个元素,但在以下情况中:

A a,b;
std::set<A> mySet;
mySet.insert(a);
mySet.insert(b);

mySet只包含一个。如果我们使用指针就不会这样。

此外,动态分配要在向量中使用的项目的原因(正如其他人所指出的)是减少插入的开销。

干杯!

答案 6 :(得分:1)

矢量是简单的容器,可以容纳任何可复制的东西。因此,根据您的需要,您可以将对象或指针放入其中的对象。

虽然集合也可以包含指针,但这样做通常没有多大意义。集是有序容器,这意味着在创建集时,需要指定比较函数。如果未指定一个,则使用默认比较函数(std::less<>),该函数取决于您在集合中存储的operator<定义的内容。这实际上似乎与指针一起使用,因为你可以将指针与<进行比较,但是它会比较指针而不是它们指向的对象,因此该集合最终会被对象在内存中的相对位置排序