Форум программистов, компьютерный форум CyberForum.ru

Заполнение map объектами класса - C++

Восстановить пароль Регистрация
 
RocBoy-D
32 / 31 / 6
Регистрация: 10.03.2012
Сообщений: 361
18.02.2014, 23:05     Заполнение map объектами класса #1
Здравствуйте! Нашел пример заполнения map таким образом:

C++
1
2
map<string, int> M;
M["One"] = 1;
Но при заполнении map аналогичным образом объектами пользовательского типа данных программа аварийно завершает свою работу:

C++
1
2
3
Queue obj ("Sokolov", "Nikita");
map <unsigned short, Queue> m;
m [9] = obj;
Конструктор объектов класса работает верно, так как map правильно заполняется методом insert. В чем может быть ошибка?
Лучшие ответы (1)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
DrOffset
6424 / 3798 / 879
Регистрация: 30.01.2014
Сообщений: 6,591
18.02.2014, 23:29     Заполнение map объектами класса #2
Цитата Сообщение от RocBoy-D Посмотреть сообщение
Queue
Давай код этого класса сюда
RocBoy-D
32 / 31 / 6
Регистрация: 10.03.2012
Сообщений: 361
19.02.2014, 01:43  [ТС]     Заполнение map объектами класса #3
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include "queue.h"
 
Queue :: Queue (): first_name (NULL), second_name (NULL) {}
 
Queue :: Queue (char *first_name, char *second_name)
{
    this -> first_name = new char [strlen (first_name) + 1];
    strcpy (this -> first_name, first_name);
    this -> second_name = new char [strlen (second_name) + 1];
    strcpy (this -> second_name, second_name);
}
 
Queue :: Queue (const Queue &obj)
{
    first_name = new char [strlen (obj.first_name) + 1];
    strcpy (first_name, obj.first_name);
    second_name = new char [strlen (obj.second_name) + 1];
    strcpy (second_name, obj.second_name);
}
 
char *Queue :: Get_first_name () const
{
    return first_name;
}
 
char *Queue :: Get_second_name () const
{
    return second_name;
}
 
Queue &Queue :: operator = (const Queue &obj)
{
    if (this == &obj)
        return *this;
 
    delete [] first_name;
    first_name = NULL;
    first_name = new char [strlen (obj.first_name) + 1];
    strcpy (first_name, obj.first_name);
    delete [] second_name;
    second_name = NULL;
    second_name = new char [strlen (obj.second_name) + 1];
    strcpy (second_name, obj.second_name);
 
    return *this;
}
 
bool operator < (const Queue &obj1, const Queue &obj2)
{
    if (!strcmp (obj1.first_name, obj2.first_name))
        return (strcmp (obj1.second_name, obj2.second_name) < 0)? true : false;
    return (strcmp (obj1.first_name, obj2.first_name) < 0)? true : false;
}
 
istream &operator >> (istream &in, Queue &obj)
{
    char first_name [80], second_name [80];
 
    cout << "Input first name: ";
    in.getline (first_name, 80);
    cout << "Input second name: ";
    in.getline (second_name, 80);
 
    obj.first_name = new char [strlen (first_name) + 1];
    strcpy (obj.first_name, first_name);
    obj.second_name = new char [strlen (second_name) + 1];
    strcpy (obj.second_name, second_name);
 
    return in;
}
 
ostream &operator << (ostream &out, Queue &obj)
{
    out << obj.first_name << " " << obj.second_name << endl; 
 
    return out;
}
 
Queue :: ~Queue ()
{
    delete [] first_name;
    first_name = NULL;
    delete [] second_name;
    second_name = NULL;
}
DrOffset
6424 / 3798 / 879
Регистрация: 30.01.2014
Сообщений: 6,591
19.02.2014, 16:18     Заполнение map объектами класса #4
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от RocBoy-D Посмотреть сообщение
Конструктор объектов класса работает верно, так как map правильно заполняется методом insert. В чем может быть ошибка?
Итак, ошибка в неправильной реализации конструктора копирования и оператора присваивания.
Правильная реализация должна быть вроде этой:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
Queue :: Queue (const Queue &obj)
    : first_name(NULL), second_name(NULL)
{
    if(obj.first_name)
    {
        first_name = new char [strlen (obj.first_name) + 1];
        strcpy(first_name, obj.first_name);
    }
    if(obj.second_name)
    {
        second_name = new char [strlen (obj.second_name) + 1];
        strcpy (second_name, obj.second_name);
    }
}
 
Queue &Queue :: operator = (const Queue &obj)
{
    if (this == &obj)
        return *this;
 
    delete [] first_name;
    first_name = NULL;
    if(obj.first_name)
    {
        first_name = new char [strlen (obj.first_name) + 1];
        strcpy (first_name, obj.first_name);
    }
    delete [] second_name;
    second_name = NULL;
    if(obj.second_name)
    {
        second_name = new char [strlen (obj.second_name) + 1];
        strcpy (second_name, obj.second_name);
    }
    return *this;
}
Иначе при попытке скопировать пустой(со значениями NULL) объект приведет к краху.
Что собственно и происходит. Из-за особенности работы operator[] у std::map.
Т.к. сначала он создает пустой объект в map с заданным ключом, а потом уже через оператор присваивания переносит содержимое твоего obj!
Если исправить код, как я показал выше, то падения не будет. Но код все равно будет не очень хорошим из-за лишних действий. Поэтому добавлять в map лучше (и эффективнее) так:
C++
1
2
    std::map <unsigned short, Queue> m;
m.insert(std::make_pair(9, Queue("Sokolov", "Nikita")));
Помимо этого есть ошибки в operator<<, operator>> и operator<, связанные с нулевым состояние твоего Queue, но исправить их предлагаю самостоятельно
Yandex
Объявления
19.02.2014, 16:18     Заполнение map объектами класса
Ответ Создать тему
Опции темы

Текущее время: 23:57. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru