Я работаю над проектом, который включает в себя набор сортов ручной работы, использующий шаблонный класс с двумя типами и векторами (которые я могу изменить на указатели, но не сейчас).
Добавление и вывод значений работает нормально, и я могу получить доступ к ключу и значениям также с помощью eachother.
Однако у меня проблемы с удалением значений. Вот код, который у меня есть для этого:
bool Remove(Tkey key)
{
for (int i = 0; i < size(); i++)
{
if (keyPtr[i] == key)
{
keyPtr.erase(keyPtr.begin() + (i-1));
valuePtr.erase(valuePtr.begin() + (i-1));
return true;
}
}
return false;
}
Так что, когда я захочу его использовать, он будет выглядеть так:
cout << "Remove Value 6" << endl;
list.Remove(6);
Что я ожидаю от векторов, так это то, что при вызове данные с ключом 6 будут удалены. Однако я получаю это как мой вывод:
Ключ: 0 Значение: 0
Ключ: 1 Значение: 3
Ключ: 2 Значение: 6
Ключ: 3 Значение: 9
Ключ: 4 Значение: 12
Ключ: 5 Значение: 15
Ключ: 6 Значение: 18
Ключ: 7 Значение: 21
Ключ: 8 Значение: 24
Ключ: 9 Значение: 27
Найти значение 5: 15
Удалить значение 6
Ключ: 0 Значение: 0
Ключ: 1 Значение: 3
Ключ: 2 Значение: 6
Ключ: 3 Значение: 9
Ключ: 4 Значение: 12
Ключ: 0 Значение: 0
Ключ: 6 Значение: 18
Ключ: 7 Значение: 21
Ключ: 8 Значение: 24
Ключ: 9 Значение: 27
Весь код класса находится в заголовке, потому что шаблоны классов не могут быть разделены между header и cpp без наличия метода main внутри файла cpp. Есть что-то, что я должен проверить, или это как-то связано с кодом внутри заголовка?
РЕДАКТИРОВАТЬ: это код, который я использую, чтобы получить вывод. Он находится в файле с именем «main.cpp»
#include <iostream>
#include <vector>
#include "DictionaryList.h"
using namespace std;void main()
{
DictionaryList<int,int> list;
for (int i = 0; i < 11; i++)
{
list.Add(i, i*3);
}
for (int i = 0; i < 10; i++)
{
cout << "Key : " << list.Exists(i*3) << " Value : " << list.Get(i) << endl;
}
cout << "Find value 5: " << list.Get(5) << endl;
cout << "Remove Value 6" << endl;
list.Remove(6);
for (int i = 0; i < 10; i++)
{
cout << "Key : " << list.Exists(i*3) << " Value : " << list.Get(i) << endl;
}
system("pause");
}
Вы получаете наблюдаемый результат, потому что:
Вы удаляете элемент 5, а не 6. Найдя индекс i
соответствующий запрошенному ключу, вы затем стираете элемент i-1
, Изменить erase
аргументы begin() + i
удалить ожидаемую пару ключ / значение.
Ваш выходной цикл печатает строку для каждого возможного ключа, независимо от того, находится он там или нет, поэтому строка говорит Key : 0 Value : 0
где был удален элемент Похоже List.Exists()
ищет значение, возвращая ключ, если он найден, и ноль, если это не так, и List.Get()
возвращает ноль, если ключ не найден. Такое поведение приведет к ошибкам: нет способа отличить отсутствующие элементы от элементов с нулевым значением.
Даже если вы по какой-то причине не хотите использовать стандартные контейнеры карты, я предлагаю предоставить вашему контейнеру аналогичный интерфейс; Помимо того, что они были знакомы людям, использующим стандартные контейнеры, мы много думали о том, чтобы сделать их интерфейсы трудными для неправильного использования.
Это выглядит очень подозрительно:
for (int i = 0; i < 10; i++)
{
cout << "Key : " << list.Exists(i*3) << " Value : " << list.Get(i) << endl;
}
Когда вы проверите для своего удаленного элемента (с ключом 5, значение 15), я буду этим list.Exists(i*3)
вернусь false
, который cout
приведут к 0
для тебя. Точно так же, держу пари, что у вас есть значение по умолчанию 0
от list.Get
, тоже!
Я считаю, что, по крайней мере, list.Get()
shoudl выдает исключение, если запрашивается отсутствующий ключ.