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_ptr
s (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.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
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.
您已为指针向量创建向量
#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_ptr
s (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.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
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.
您已为指针向量创建向量
#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