C++ 是否可以创建指针向量?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/817263/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is it possible to create a vector of pointers?
提问by Logan Capaldo
Just wondering, because of a problem I am running into, is it possible to create a vector of pointers? And if so, how? Specifically concerning using iterators and .begin() with it, ie: How would I turn this vector into a vector of pointers:
只是想知道,由于我遇到的一个问题,是否可以创建一个指针向量?如果是这样,如何?特别是关于使用迭代器和 .begin() ,即:我将如何将此向量转换为指针向量:
class c
{
void virtual func();
};
class sc:public c
{
void func(){cout<<"using func";}
};
sc cobj;
vector<c>cvect
cvect.push_back(cobj);
vector<c>::iterator citer
for(citer=cvect.begin();citer<cvect.end();citer++)
{
citer->func();
}
回答by Logan Capaldo
Sure.
当然。
vector<c*> cvect;
cvect.push_back(new sc);
vector<c*>::iterator citer;
for(citer=cvect.begin(); citer != cvect.end(); citer++) {
(*citer)->func();
}
Things to keep in mind:
要记住的事情:
You'll need to cleanup after your self if you use dynamically allocated memory as I did in my example
如果您像我在示例中那样使用动态分配的内存,则需要在自己之后进行清理
e.g.:
例如:
for(...) { delete *i; }
This can be simplified by using a vector of shared_ptr
s (like boost::shared_ptr
). Do not attempt to use std::auto_ptr
for this, it will not work (won't even compile).
这可以通过使用shared_ptr
s的向量(如boost::shared_ptr
)来简化。不要尝试使用std::auto_ptr
它,它不会工作(甚至不会编译)。
Another thing to keep in mind, you should avoid using <
to compare iterators in your loop when possible, it will only work for iterators that model a random access iterator, which means you can't change out your code to use e.g. a std::list
.
要记住的另一件事,您应该尽可能避免<
在循环中使用比较迭代器,它仅适用于对随机访问迭代器建模的迭代器,这意味着您无法更改代码以使用例如 a std::list
。
回答by Logan Capaldo
vector <c> cvect
is not a vector of pointers. It is a vector of objects of type c. You want vector <c*> cvect
. and the you probably want:
vector <c> cvect
不是指针向量。它是一个类型为 c 的对象的向量。你要vector <c*> cvect
。你可能想要的:
cvect.push_back( new c );
And then, given an iterator, you want something like:
然后,给定一个迭代器,你想要这样的东西:
(*it)->func();
Of course, it's quite probable you didn't want a vector of pointers in the first place...
当然,很可能你一开始并不想要一个指针向量......
回答by j_random_hacker
Yes it is possible, and in fact it is necessaryto use pointers if you intend your vector to contain objects from an entire class hierarchy rather than of a single type. (Failing to use pointers will result in the dreaded problem of object slicing-- all objects are silently converted to base class type. This is not diagnosed by the compiler, and is almost certainly not what you want.)
是的,这是可能的,实际上,如果您希望向量包含来自整个类层次结构而不是单一类型的对象,则有必要使用指针。(不使用指针会导致可怕的对象切片问题——所有对象都被默默地转换为基类类型。编译器没有诊断出这一点,而且几乎肯定不是你想要的。)
class c
{
void virtual func();
};
class sc:public c
{
void func(){cout<<"using func";}
};
sc cobj;
vector<c*> cvect; // Note the type is "c*"
cvect.push_back(&cobj); // Note the "&"
vector<c*>::iterator citer;
for(citer=cvect.begin();citer != cvect.end();citer++) // Use "!=" not "<"
{
(*citer)->func();
}
Note that with a vector of pointers, you need to do your own memory management, so be very careful -- if you will be using local objects (as above), they must not fall out of scope before the container does. If you use pointers to objects created with new
, you'll need to delete
them manually before the container is destroyed. You should absolutely consider using smart pointers in this case, such as the smart_ptr
provided by Boost
.
请注意,对于指针向量,您需要进行自己的内存管理,因此要非常小心——如果您将使用本地对象(如上所述),则它们不能在容器使用之前超出范围。如果您使用指向创建的对象的指针new
,则需要delete
在销毁容器之前手动使用它们。你绝对应该考虑使用在这种情况下,智能指针,如smart_ptr
提供Boost
。
回答by Naveen
You have create vector<c*>
for a vector of pointers. Then use new
to allocate the memory for c objects and push them into vector. Also, don't forget that you have to delete
yourself and vector.clear() will not release the memory allocated for c objects. You have to store c as a vector of pointers here, otherwise the call to the virtual function will not work.
您已经创建vector<c*>
了一个指针向量。然后使用new
为 c 对象分配内存并将它们推入向量。另外,不要忘记你必须delete
自己并且 vector.clear() 不会释放为 c 对象分配的内存。您必须在此处将 c 存储为指针向量,否则对虚函数的调用将不起作用。
回答by Gant
Yes, sure.
是的,当然。
// TestCPP.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <vector>
using namespace std;
class c
{
public:
void virtual func() = 0;
};
class sc:public c
{
public:
void func(){cout<<"using func";}
};
int _tmain(int argc, _TCHAR* argv[])
{
sc cobj;
vector<c*> cvect;
cvect.push_back(&cobj);
vector<c*>::iterator citer;
for(citer=cvect.begin();citer<cvect.end();citer++)
{
(*citer)->func();
}
return 0;
}
Please note the declaration of vector<c*> cvect
and the use of cvect.push_back(&cobj)
.
请注意 的声明vector<c*> cvect
和使用cvect.push_back(&cobj)
。
From the code provided, you are using iterator in a wrong way. To access the member an iterator is pointing to you must use *citer
instead of citer
alone.
从提供的代码来看,您以错误的方式使用迭代器。要访问迭代器指向的成员,您必须使用*citer
而不是citer
单独使用。
回答by Gant
Try Boost Pointer Container Library. It has several advantages over regular vector of pointers, like:
试试Boost Pointer Container Library。与常规的指针向量相比,它有几个优点,例如:
my_container.push_back( 0 ); // throws bad_ptr
ptr_vector<X> pvec;
std::vector<X*> vec;
( *vec.begin() )->foo(); // call X::foo(), a bit clumsy
pvec.begin()->foo(); // no indirection needed