Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.62/13: Рейтинг темы: голосов - 13, средняя оценка - 4.62
TLENS
-7 / 2 / 0
Регистрация: 11.10.2011
Сообщений: 79
1

Как передавать ссылку на структуру в map?

13.05.2012, 01:21. Просмотров 2585. Ответов 22
Метки нет (Все метки)

Надо два контейнера один вектор со структурами второй мап с сылками на те структуры.
Но вот проблема в map<int, Test*> itag после новой записи предыдущая ссылка ведет на непонятную структуру в которой itag[key]->t = <неверный указатель а itag[key]->i = переполнение;
Я возможно не совсем понял основу. На манах просидел чета не найду подходящего примера.
пробовал и через инссерт тоже самое.
Подскажите как правильно?
спс!
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct Test {
    string t;
    int i;
};
int main () {
    int test;
    vector<Test> data;
    map< int, Test*> itag;
    for (int i = 0; i < 10; i ++) {
        data.push_back(struct Test());
        data.back().t = '0' + i;
        data.back().i = i;
        itag[i] = &data.back();
    }
    getchar();
}
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.05.2012, 01:21
Ответы с готовыми решениями:

Как передавать структуру в функцию?
Вопрос глупый, возможно, но я совсем не понимаю, как. Есть у меня в программе стркутура: struct...

Как передавать структуру в массив?
А заполнять его как обычный массив??? через цикл?

Есть ли аналог Map <String,String> чтобы передавать его как указатель на данные?
Добрый день, подскажите, есть ли аналог Map &lt;String,String&gt; чтобы передавать его как указатель на...

Как передать в функцию ссылку на структуру?
Добрый вечер, помогите пожалуйста разобраться. Нужно чтобы функция myProc принимала не структуру, а...

Можно ли передавать ссылку процедуры как параметр?
Здравсвтуйте,можно ли передавать ссылку процедуры как параметр ? и как принимать ?,заранее спасибо....

22
grizlik78
Эксперт С++
2063 / 1533 / 218
Регистрация: 29.05.2011
Сообщений: 3,182
13.05.2012, 02:03 2
Всё просто. В векторе после push_back() может происходить перераспределение памяти и тогда все итераторы, ссылки и указатели на элементы этого вектора становятся недействительными. Решение первое: сначала создать и заполнить весь вектор целиком, а только потом запихивать ссылки на элементы в мап. Решение второе: обеспечить достаточный размер вектора перед вставками путём вызова data.reserve(сколько_надо_элементов).
1
Avazart
Эксперт С++
7959 / 5780 / 571
Регистрация: 10.12.2010
Сообщений: 26,569
Записей в блоге: 17
13.05.2012, 02:07 3
Ну вектор такая подлая вещь что может твой элемент перенести из одного места(памяти) в другое при расширении используя конструктор копий.

Как вариант создавать vector<Test*> data; а структуры динамически
0
grizlik78
Эксперт С++
2063 / 1533 / 218
Регистрация: 29.05.2011
Сообщений: 3,182
13.05.2012, 02:07 4
Но, кажется, здесь ещё одна ошибка:
Цитата Сообщение от TLENS Посмотреть сообщение
&data.back();
если data.back() возвращает копию, а не ссылку. Но тут я не помню, надо в стандарт слазить.
0
13.05.2012, 02:07
Avazart
Эксперт С++
7959 / 5780 / 571
Регистрация: 10.12.2010
Сообщений: 26,569
Записей в блоге: 17
13.05.2012, 02:10 5
если data.back() возвращает копию, а не ссылку
Ссылку http://www.cplusplus.com/reference/stl/vector/back/
0
TLENS
-7 / 2 / 0
Регистрация: 11.10.2011
Сообщений: 79
13.05.2012, 02:12  [ТС] 6
grizlik78, Полюбом спс. Я читал за вектор как он работает с памятью но как то вылетело из головы.
Я новичок в С++ две недели как знаком с ним. Перед этим на пыхе плотно кодил здесь сложнее воспринимается так как с памятью уже сам работаю.

Добавлено через 2 минуты
Avazart, Вообщето я извлекал ссылку &data.back();
P.S. Я видел этот сайт и перечитал раза 5 все методы.
0
Avazart
Эксперт С++
7959 / 5780 / 571
Регистрация: 10.12.2010
Сообщений: 26,569
Записей в блоге: 17
13.05.2012, 02:14 7
Кстати удаление вызывает те же проблемы.
1
TLENS
-7 / 2 / 0
Регистрация: 11.10.2011
Сообщений: 79
13.05.2012, 02:16  [ТС] 8
Цитата Сообщение от grizlik78 Посмотреть сообщение
Но, кажется, здесь ещё одна ошибка:

если data.back() возвращает копию, а не ссылку. Но тут я не помню, надо в стандарт слазить.
А я понял. в смысле работа будет не с самой структурой с вектора а с копией ?

Добавлено через 1 минуту
Avazart, Сори ты был прав. Сейчас протестирую влияние через ссылку
0
grizlik78
Эксперт С++
2063 / 1533 / 218
Регистрация: 29.05.2011
Сообщений: 3,182
13.05.2012, 02:21 9
Цитата Сообщение от Avazart Посмотреть сообщение
Кстати удаление вызывает те же проблемы.
Удаление из хвоста не вызывает. Удаление из середины делает недействительными ссылки, итераторы и указатели на элементы начиная с удаляемого.

Добавлено через 2 минуты
Цитата Сообщение от TLENS Посмотреть сообщение
А я понял. в смысле работа будет не с самой структурой с вектора а с копией ?
Да, но это если бы .back() возвращал не ссылку.
0
TLENS
-7 / 2 / 0
Регистрация: 11.10.2011
Сообщений: 79
13.05.2012, 02:25  [ТС] 10
Таки нет, действует Влияние на ссылку извлеченную с возврата vector::back();
Собственно я повлиял таким тестом.
C++
1
2
3
4
5
6
7
8
9
10
11
struct T{
    int t;
};
int main () {
    vector<T> v;
    v.push_back(T());
    v.back().t = 2;
    T *t = &v.back();
    t->t = 5;
    cout << v.back().t << endl;
    getchar();
В оутпут получил 5
Но все же вывод таков что ссылкой пользоваться нежелательно в таком случае так как при увеличении массива ссылки поменяются
0
grizlik78
Эксперт С++
2063 / 1533 / 218
Регистрация: 29.05.2011
Сообщений: 3,182
13.05.2012, 02:27 11
TLENS, постарайся ещё разобраться что есть ссылка, а что указатель. Это очень близкие понятия, но не одно и то же.
0
Avazart
Эксперт С++
7959 / 5780 / 571
Регистрация: 10.12.2010
Сообщений: 26,569
Записей в блоге: 17
13.05.2012, 02:27 12
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
struct Test {
    string t;
    int i;
};
//----------------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
system("chcp 1251");
 
    int test;
    vector<Test> data;
    data.reserve(10);// резервная память под 10 элементов
    map< int, Test*> itag;
    for (int i = 0; i < 10; i ++) {
        data.push_back(Test());
        data.back().t = '0' + i;
        data.back().i = i;
        itag[i] = &data.back();
    }
 
for (int i = 0; i < 10; i ++) cout<< (*itag[i]).t <<endl; // тест
 
 
system("pause");
return 0;
}
Но все же вывод таков что ссылкой пользоваться нежелательно в таком случае так как при увеличении массива ссылки поменяются
Ну поэтому я и советую изменить объекты указателями на объекты, но это все зависит от ситуации по тому как возникает проблема с согласованным удалением
1
TLENS
-7 / 2 / 0
Регистрация: 11.10.2011
Сообщений: 79
13.05.2012, 02:41  [ТС] 13
Каким образом структура сменилась?

Добавлено через 3 минуты
grizlik78, Я как раз так и подумал уже начал искать ман по указателях))
Указатель например передается в функцию таким образом
C++
1
int f(struct t&);
по крайней мере я так на php работал.
Это и есть указатель?

Добавлено через 6 минут
Ладно всем спасибо. Все понял.
0
grizlik78
Эксперт С++
2063 / 1533 / 218
Регистрация: 29.05.2011
Сообщений: 3,182
13.05.2012, 02:43 14
Если t название типа структуры, то это как-раз передача по ссылке.
C++
1
2
3
4
5
6
int abc = 123; // обычная целочисленная переменная
int *p = NULL; // переменная-указатель. Никуда не указывает.
int & ref = abc; // ссылка на переменную abc. Фактически ref становится псевдонимом abc
p = &abc; // указатель теперь указывает на abc
ref = 321; // изменяем переменную по ссылке
*p = 666; // изменяем переменную по указателю
1
Avazart
Эксперт С++
7959 / 5780 / 571
Регистрация: 10.12.2010
Сообщений: 26,569
Записей в блоге: 17
13.05.2012, 02:47 15
Указатель- переменная содержащая адрес расположения другой переменной

Вариант с указателями
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
using namespace std;
 
struct Test {
    string t;
    int i;
};
//---------------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
system("chcp 1251");
 
    int test;
    vector<Test*> data;
    map<int, Test*> itag; // !!!
    for (int i = 0; i < 10; i ++) {
 
        Test* test = new Test;
        test->i=i;
        test->t='a'+i;
 
        data.push_back(test);
        itag[i]= test;
    }
 
for (int i = 0; i < 10; i ++) cout<< itag[i]->t <<endl;// Test
// удаление  и очистка
for (int i = 0; i < 10; i ++) delete data[i];
data.clear();
itag.clear();
 
system("pause");
return 0;
}
//---------------------------------------------------------------------------
0
TLENS
-7 / 2 / 0
Регистрация: 11.10.2011
Сообщений: 79
13.05.2012, 02:56  [ТС] 16
А я спутал местами ссылку и указатель.

Добавлено через 4 минуты
grizlik78, Все я это понимаю.
Подумал что int *p Это ссылка а int & p это указатель.
0
Avazart
Эксперт С++
7959 / 5780 / 571
Регистрация: 10.12.2010
Сообщений: 26,569
Записей в блоге: 17
13.05.2012, 02:58 17
Разница в том что к указателю можно примениять арифметические действия.
0
grizlik78
Эксперт С++
2063 / 1533 / 218
Регистрация: 29.05.2011
Сообщений: 3,182
13.05.2012, 02:59 18
Ладно, раз понимаешь, тогда постараюсь запутать. В моём коде &abc это указатель, а *p это, фактически, безымянная ссылка
0
TLENS
-7 / 2 / 0
Регистрация: 11.10.2011
Сообщений: 79
13.05.2012, 03:02  [ТС] 19
Секунду

Добавлено через 1 минуту
Хм....
0
Avazart
Эксперт С++
7959 / 5780 / 571
Регистрация: 10.12.2010
Сообщений: 26,569
Записей в блоге: 17
13.05.2012, 03:09 20
Я б не прочь, но возможно стоит создать новую тему, а то админы ругаться могут...

Добавлено через 2 минуты
Кстати если не кртично то можно было бы использовать std::list<> вместо вектора решив проблему порчи имущества

Добавлено через 3 минуты
grizlik78 из-за подобных вещей как я пологаю С# объекты ссылочного типа...
0
13.05.2012, 03:09
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.05.2012, 03:09

Как передавать ссылку на экземпляр класса между Activity?
Если в MainActivity я создаю ссылку (SaveDataObj ) на класс и выделяю память (new SaveData()) под...

Как передать ссылку на структуру в поток?
Если запускать поток с параметром, то этот параметр передается копированием. А как передать ссылку?...

Передавать не ссылку, а объект
Вообщем: У меня есть интерфейс Int: public interface Intr { double Length { get; set; }...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.