Я пытался разобраться с использованием пользовательских типов (или классов) со стандартными контейнерами библиотеки C ++ - векторами. Я хочу иметь возможность делать обычные вещи, которые мне удобно делать с векторами встроенных типов C ++, int, float, string и т. Д. c .. но с моими собственными определенными типами. Я написал небольшой пример программы, использующей класс box
, чтобы попытаться понять, что происходит.
Вот код для класса:
class box {
private:
float *lengthPtr;
std::string *widthPtr;
public:
box(float a, std::string b) {
std::cout<<"Constructor called" << '\n';
lengthPtr = new float;
*lengthPtr = a;
widthPtr = new std::string;
*widthPtr = b;
}
// copy constructor
box(const box &obj){
std::cout<< "User defined copy constructor called" << '\n';
lengthPtr = new float;
*lengthPtr = obj.check_length();
widthPtr = new std::string;
*widthPtr = obj.check_width();
}
// copy assignment operator
box& operator=(const box &that) {
std::cout<< "Copy assignment operator called";
float *localLen = new float;
*localLen = that.check_length();
delete[] lengthPtr;
lengthPtr = localLen;
std::string *localWid = new std::string;
*localWid = that.check_width();
delete[] widthPtr;
widthPtr = localWid;
return *this;
}
~box() {
std::cout << "User defined destructor called." << '\n';
delete lengthPtr;
delete widthPtr;
}
float check_length () const {
return *lengthPtr;
}
std::string check_width() const{
return *widthPtr;
}
void set_legnth(const float len) {
*lengthPtr = len;
}
void set_width(const std::string str) {
*widthPtr = str;
}
void print_box_info(){
std::cout << *lengthPtr << " " << *widthPtr << '\n';
}
};
Две основные вещи sh Чтобы иметь возможность сделать следующее:
Добавьте произвольное число новых элементов моего пользовательского типа (box
) к вектору, используя .push_back()
.
После сохранения своих элементов я хочу отсортировать их, используя std::sort
с определенной пользователем функцией сравнения.
Это основная функция, которую я использовал для проверки моих 2 целей:
int main() {
srand(time(NULL));
int i = 0;
std::vector<box> boxes;
while (i<25) {
int x = rand()%100+1;
std::cout<< "x = " << x << '\n';
if ( i < 5)
boxes.push_back(box(x, "name"));
if ( i > 4 && i < 12)
boxes.push_back(box(x, "Agg"));
if ( i > 11 && i < 20 )
boxes.push_back(box(x, "Cragg"));
if (i>19)
boxes.push_back(box(x, "Lagg"));
std::cout << "Added the new box to the collection." << '\n';
i++;
}
for(unsigned int j = 0; j<boxes.size(); j++) {
boxes[j].print_box_info();
}
std::sort(boxes.begin(), boxes.end(), type_is_less);
}
Код, который я написал до сих пор, кажется способным выполнить задачу 1. После запуска программы, для l oop через некоторое время l oop печатает информацию о 25 ящиках, хранящихся в векторе моих ящиков. Однако, когда я пытаюсь отсортировать свои ящики, используя std::sort
и функцию type_is_less()
:
bool type_is_less(const box &a, const box &b) {
std::cout<<"In type is less." << '\n';
std::string A = a.check_width();
std::string B = b.check_width();
std::cout<< "Comparing box a, width = " << A << '\n';
std::cout<< "with box b, width = " << B << '\n';
bool val = A<B;
std::cout << "Returning " << val <<'\n' <<'\n';
return A<B;
}
, я получаю ошибку сегментации, но я не уверен, откуда исходит ошибка. Определяемый пользователем конструктор копирования представляется последней функцией, вызываемой до возникновения ошибки сегмента. Кажется, конструктор копирования можно использовать в push_back()
, но это вызывает проблемы в std::sort
?
Я попытался отладить конструктор копирования с сообщениями std::cout
между каждой строкой и каждой строкой копии. Конструктор, кажется, выполняется, не вызывая ошибку сегмента. Ошибка seg появляется, как только завершается выполнение конструктора копирования. Конец моей консоли выводится ниже (// я вставил комментарии, используя '//'):
Добавлен новый блок в коллекцию.
3 name
// ...
// ...
// программа печатает 2 информационных точки для каждого блока
61 Lagg // Это окончательная информация о коробке печати.
В типе меньше. Сравнивая поле a, ширина = имя с полем b, ширина = Cragg Возвращает 0
В типе меньше. Сравнивая поле a, ширина = имя с полем b, ширина = Lagg Возвращает 0
В типе меньше. Поле сравнения a, width = Cragg с полем b, width = Lagg Возвращает 1
Определенный пользователем конструктор копирования с именем
Ошибка сегментации (ядро сброшено)
Есть несколько движущихся частей здесь, и я не уверен, как выяснить, какая часть моего кода ведет себя неправильно. Кажется, все указывает на то, что виновником является пользовательский конструктор копирования, но я не уверен, как его настроить. Любой совет будет высоко ценится.
Открытый вопрос, который мне еще предстоит выяснить, состоит в том, могу ли я определить класс, аналогичный этому, но с переменными без указателей lengthPtr
и widthPtr
, и при этом иметь те же функции.