Разве Итератор в C++ не является своего рода указателем?

Хорошо на этот раз я решил составить список с помощью STL. Я должен создать выделенный сокет TCP для каждого клиента. Таким образом, каждый раз у меня есть соединение, я инстанцирую сокета и добавляю указатель на него в списке.

list<MyTcp*> SocketList;  //This is the list of pointers to sockets
list<MyTcp*>::iterator it;  //An iterator to the list of pointers to TCP sockets.

Помещение нового указателя на сокет было легко, но теперь каждый раз концы соединения я должен разъединить сокет и удалить указатель, таким образом, я не получаю огромную утечку памяти, правильно? хорошо.. Я думал, что делал хорошо путем установки этого:

it=SocketList.begin();
while( it != SocketList.end() ){
    if((*it)->getClientId() == id){
    pSocket = it; //    <-------------- compiler complains at this line
    SocketList.remove(pSocket);
    pSocket->Disconnect();
    delete pSocket;
    break;
    }
}

Но в компиляторе говорится это:

 error: invalid cast from type ‘std::_List_iterator<MyTcp*>’ to type ‘MyTcp*’

Кто-то может помочь мне здесь? я думал, что делал вещи правильно, итератор в любой момент времени просто не указывает на один из элементов набора? как я могу зафиксировать его?

5
задан Bilthon 18 April 2010 в 03:49
поделиться

4 ответа

Попробуйте следующее:

pSocket = *it; 

Итераторы действуют во многом как указатели, но на самом деле они могут быть указатель или полноценный класс, который действует как один. В этом случае важно то, что при разыменовании одного объекта вы получите тот элемент, который хранится в контейнере. Поскольку вы сохраняете в списке MyTcp * , при разыменовании итератора вы получаете MyTcp * . pSocket относится к типу MyTcp * , поэтому указанное выше присвоение выполняется успешно. Присваивание, которое вы пытаетесь выполнить, не разыменовывает итератор - вы пытаетесь назначить сам итератор pSocket .

Это похоже на следующий случай:

void foo()
{
    MyTcp *array[10]; // An array full of MyTcp pointers
    MyTcp **iterator = NULL; // pointers make good iterators for arrays (but not for std::lists)
    for (iterator = array; iterator != array + 10; ++iterator)
    {
        // This fails to compile (cannot assign MyTcp** to MyTcp*:
        MyTcp *wrong = iterator;            

        // This succeeds:
        MyTcp *current = *iterator; // important to dereference the iterator
    }
} 
18
ответ дан 18 December 2019 в 05:40
поделиться

Итератор может быть реализован с помощью указателя (в случае вектора это так). Итераторы имеют семантику указателя - вы разыменовываете их, чтобы получить значение.

Но вы храните указатели в списке. «MyTcp *» - это ваше значение, поэтому для его присвоения вы разыменовываете «it».

pSocket = *it;
4
ответ дан 18 December 2019 в 05:40
поделиться

Итератор - это обобщение указателя. В Википедии есть хорошая статья о шаблоне итератора.

Итераторы используются в STL для того, чтобы сделать алгоритмы ортогональными контейнерам. Любой контейнер может использоваться с (почти) любым алгоритмом, если этот контейнер поддерживает итераторы.

6
ответ дан 18 December 2019 в 05:40
поделиться

Итератор просто указывает на один из элементов, и синтаксис для его разыменования тот же, но это другой тип (с другим представлением в памяти), и арифметика указателя на нем делает что-то другое, чем это делает. на указатель (то есть результат арифметики итератора указывает на другую ячейку памяти, чем вы получили бы, если бы вы преобразовали итератор в указатель и выполнили арифметику указателя), поэтому обычно вы не хотите путать эти два типа.

Однако, учитывая типы, которые ваш список представляет собой список указателей, и вы разыменовываете pSocket только один раз в вызове pSocket-> Disconnect (); , я думаю Ответ Eclipse - это то, что вы хотите: pSocket = * it;

3
ответ дан 18 December 2019 в 05:40
поделиться
Другие вопросы по тегам:

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