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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 17:24:55  来源:igfitidea点击:

Is it possible to create a vector of pointers?

c++stlpointersvectorpure-virtual

提问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_ptrs (like boost::shared_ptr). Do not attempt to use std::auto_ptrfor 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.

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

回答by Logan Capaldo

vector <c> cvectis 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 deletethem manually before the container is destroyed. You should absolutely consider using smart pointers in this case, such as the smart_ptrprovided by Boost.

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

回答by Naveen

You have create vector<c*>for a vector of pointers. Then use newto allocate the memory for c objects and push them into vector. Also, don't forget that you have to deleteyourself 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*> cvectand 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 *citerinstead of citeralone.

从提供的代码来看,您以错误的方式使用迭代器。要访问迭代器指向的成员,您必须使用*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