是否可以创建指针向量?

时间:2021-10-15 16:10:16

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();
}

6 个解决方案

#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_ptrs (like boost::shared_ptr). Do not attempt to use std::auto_ptr for this, it will not work (won't even compile).

这可以通过使用shared_ptrs的向量(如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.

另外要记住的是,你应该避免在可能的情况下使用 <来比较循环中的迭代器,它只适用于为随机访问迭代器建模的迭代器,这意味着你无法更改代码以便使用,例如一个std :: list。< p>

#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:

vector cvect不是指针的向量。它是c类型的对象的向量。你想要vector 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...

当然,很可能你首先不想要一个指针矢量......

#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.

请注意,使用指针向量,您需要进行自己的内存管理,因此要非常小心 - 如果您将使用本地对象(如上所述),它们必须在容器之前不会超出范围。如果使用指向使用new创建的对象的指针,则需要在销毁容器之前手动删除它们。在这种情况下,您应该绝对考虑使用智能指针,例如Boost提供的smart_ptr。

#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).

请注意vector 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。

#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.

您已为指针向量创建向量 。然后使用new为c对象分配内存并将它们推送到向量中。另外,不要忘记你必须删除自己,vector.clear()不会释放为c对象分配的内存。你必须在这里存储c作为指针的向量,否则对虚函数的调用将不起作用。

#6


Try Boost Pointer Container Library. It has several advantages over regular vector of pointers, like:

尝试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

#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_ptrs (like boost::shared_ptr). Do not attempt to use std::auto_ptr for this, it will not work (won't even compile).

这可以通过使用shared_ptrs的向量(如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.

另外要记住的是,你应该避免在可能的情况下使用 <来比较循环中的迭代器,它只适用于为随机访问迭代器建模的迭代器,这意味着你无法更改代码以便使用,例如一个std :: list。< p>

#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:

vector cvect不是指针的向量。它是c类型的对象的向量。你想要vector 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...

当然,很可能你首先不想要一个指针矢量......

#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.

请注意,使用指针向量,您需要进行自己的内存管理,因此要非常小心 - 如果您将使用本地对象(如上所述),它们必须在容器之前不会超出范围。如果使用指向使用new创建的对象的指针,则需要在销毁容器之前手动删除它们。在这种情况下,您应该绝对考虑使用智能指针,例如Boost提供的smart_ptr。

#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).

请注意vector 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。

#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.

您已为指针向量创建向量 。然后使用new为c对象分配内存并将它们推送到向量中。另外,不要忘记你必须删除自己,vector.clear()不会释放为c对象分配的内存。你必须在这里存储c作为指针的向量,否则对虚函数的调用将不起作用。

#6


Try Boost Pointer Container Library. It has several advantages over regular vector of pointers, like:

尝试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