只是想知道,因为我遇到了一个问题,是否可以创建一个指针向量?如果是这样,怎么样?特别是关于使用迭代器和.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();
}
答案 0 :(得分:17)
不确定
vector<c*> cvect;
cvect.push_back(new sc);
vector<c*>::iterator citer;
for(citer=cvect.begin(); citer != cvect.end(); citer++) {
(*citer)->func();
}
要记住的事情:
如果你像我在我的例子中那样使用动态分配的内存,你需要自己清理。
e.g:
for(...) { delete *i; }
这可以通过使用shared_ptr
s的向量(如boost::shared_ptr
)来简化。不要试图使用std::auto_ptr
,它不起作用(甚至不会编译)。
要记住的另一件事是,你应该尽可能避免使用<
来比较循环中的迭代器,它只适用于为随机访问迭代器建模的迭代器,这意味着你无法更改你的代码使用,例如std::list
。
答案 1 :(得分:8)
vector <c> cvect
不是指针的向量。它是c类型的对象矢量。你想要vector <c*> cvect
。你可能想要:
cvect.push_back( new c );
然后,给定一个迭代器,你需要类似的东西:
(*it)->func();
当然,很可能你首先不想要一个指针矢量......
答案 2 :(得分:4)
是的,如果您希望向量包含整个类层次结构中的对象而不是单个类型,则使用指针实际上是必需。 (未使用指针将导致object slicing的可怕问题 - 所有对象都被静默转换为基类类型。这不是由编译器诊断的,几乎肯定不是你想要的。)
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();
}
请注意,使用指针向量,您需要进行自己的内存管理,所以要非常小心 - 如果您将使用本地对象(如上所述),它们一定不会丢失容器之前的范围。如果您使用指向使用new
创建的对象的指针,则在销毁容器之前,您需要手动delete
它们。在这种情况下,您绝对应该考虑使用智能指针,例如Boost
提供的smart_ptr
。
答案 3 :(得分:2)
您已为指针向量创建vector<c*>
。然后使用new
为c对象分配内存并将它们推送到向量中。另外,不要忘记你必须自己delete
而vector.clear()不会释放为c对象分配的内存。你必须在这里存储c作为指针的向量,否则对虚函数的调用将不起作用。
答案 4 :(得分:2)
是的,当然。
// 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;
}
请注意vector<c*> cvect
的声明以及cvect.push_back(&cobj)
的使用。
从提供的代码中,您以错误的方式使用迭代器。要访问迭代器指向的成员,必须单独使用*citer
而不是citer
。
答案 5 :(得分:0)
试试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