可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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:
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();
}
回答1:
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).
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
.
回答2:
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:
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...
回答3:
Yes it is possible, and in fact it is necessary to 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
.
回答4:
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)
.
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.
回答5:
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.
回答6:
Try Boost Pointer Container Library. It has several advantages over regular vector of pointers, like:
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