Действительно ли возможно создать вектор указателей?

Вам просто нужна специализация для обработки типа указателя на функцию:

template <typename Sig> struct argument_of;
template <typename R, typename Arg> struct argument_of<R(Arg)> { typedef Arg type; };
template <typename R, typename Arg> struct argument_of<R(*)(Arg)> { typedef Arg type; };

Это небольшое отличие, и я надеюсь, что я правильно понял терминологию, но символ bar - это не перегруженная функция типа void(int), тогда как переменная f (или неназванный параметр F) является указателем на функцию [ 1112] типа void(*)(int). Переменные и функции принципиально отличаются в C ++, и система типов имеет это различие.

Также стоит отметить, что другой вариант, для которого вы, возможно, захотите специализироваться, - это ссылка на функцию , которая будет выглядеть как void(&)(int). Тип ссылки на функцию может быть выведен в ситуациях, таких как decltype(*f) или decltype((bar)) (обратите внимание на дополнительные скобки).

6
задан 3 May 2009 в 14:59
поделиться

6 ответов

vector cvect is not a vector of pointers. It is a vector of objects of type c. You want vector cvect. and the you probably want:

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

8
ответ дан 8 December 2019 в 02:46
поделиться

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 cvect and the use of 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.

2
ответ дан 8 December 2019 в 02:46
поделиться

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.

4
ответ дан 8 December 2019 в 02:46
поделиться

Конечно.

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_ptr s (например, boost :: shared_ptr ). Не пытайтесь использовать для этого std :: auto_ptr , он не будет работать (даже не будет компилироваться).

Еще одна вещь, которую следует иметь в виду, следует избегать использования < чтобы сравнивать итераторы в вашем цикле, когда это возможно, он будет работать только для итераторов, которые моделируют итератор с произвольным доступом, что означает, что вы не можете изменить свой код для использования, например, std :: list .

17
ответ дан 8 December 2019 в 02:46
поделиться

You have create vector 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.

2
ответ дан 8 December 2019 в 02:46
поделиться

Попробуйте Библиотеку контейнеров повышения указателя . Он имеет несколько преимуществ перед обычным вектором указателей, например:

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
0
ответ дан 8 December 2019 в 02:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: