8

只是想知道,由于我遇到的一个问题,是否可以创建一个指针向量?如果是这样,怎么办?特别是关于使用迭代器和 .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();
}
4

6 回答 6

17

当然。

vector<c*> cvect;
cvect.push_back(new sc);
vector<c*>::iterator citer;
for(citer=cvect.begin(); citer != cvect.end(); citer++) {
  (*citer)->func();
}

要记住的事情:

如果您像我在示例中所做的那样使用动态分配的内存,则需要在您自己之后进行清理

例如:

 for(...) { delete *i; }

这可以通过使用shared_ptrs 的向量(如boost::shared_ptr)来简化。不要尝试使用std::auto_ptr它,它不会工作(甚至不会编译)。

要记住的另一件事是,您应该尽可能避免<在循环中使用比较迭代器,它仅适用于对随机访问迭代器建模的迭代器,这意味着您不能更改代码以使用例如 a std::list

于 2009-05-03T15:08:48.413 回答
9

vector <c> cvect不是指针向量。它是类型 c 的对象的向量。你想要vector <c*> cvect。你可能想要:

cvect.push_back( new c );

然后,给定一个迭代器,你想要这样的东西:

(*it)->func();

当然,很可能你一开始就不想要一个指针向量......

于 2009-05-03T15:01:15.560 回答
4

是的,这是可能的,事实上,如果您希望向量包含来自整个类层次结构而不是单一类型的对象,则有必要使用指针。(不使用指针将导致可怕的对象切片问题——所有对象都默默地转换为基类类型。编译器不会诊断出这种情况,而且几乎可以肯定这不是你想要的。)

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在容器被销毁之前手动使用它们。在这种情况下,您绝对应该考虑使用智能指针,例如smart_ptr.Boost

于 2009-05-03T15:10:15.820 回答
2

您已经创建vector<c*>了一个指针向量。然后用于new为 c 对象分配内存并将它们推送到向量中。另外,不要忘记你必须delete自己和 vector.clear() 不会释放分配给 c 对象的内存。您必须在此处将 c 存储为指针向量,否则对虚函数的调用将不起作用。

于 2009-05-03T15:03:00.707 回答
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单独使用。

于 2009-05-03T15:07:52.627 回答
0

试试Boost 指针容器库。与常规的指针向量相比,它有几个优点,例如:

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
于 2009-05-04T22:10:31.027 回答