Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.75/8: Рейтинг темы: голосов - 8, средняя оценка - 4.75
1 / 1 / 1
Регистрация: 11.11.2012
Сообщений: 23
1

Не могу понять, как правильно передать указатель на объект в файл

01.03.2014, 17:37. Показов 1550. Ответов 8
Метки нет (Все метки)

Есть вектор v, который надо отсортировать. Есть класс MergeSort, который это должен делать, он содержит в качестве параметра указатель на вектор. Т.е. я хотел сделать так, что за конкретным объектом класса закреплялся бы навсегда конкретный вектор, и вызывая элемент-функцию .sort(), всегда можно было бы отсортировать закрепленный за классом вектор. Но вот не задача, если поменять вектор, и после этого вызвать упомянутую выше ф-ию, то она ровным счетом ничего не делает. Почему так происходит, и как это исправить?

Вот собственно код:
main.cpp
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
#include <iostream>
using std::cout;
using std::endl;
using std::cin;
#include <cstdlib>
using std::rand;
using std::srand;
#include <vector>
using std::vector;
#include <ctime>
#include "MergeSort.h"
 
void printVector(const vector<int>&);
void fillVector(vector<int> &, int);
 
int main()
{
    vector<int> v;
 
    MergeSort object(v); // Tak ne sortiruet
    fillVector(v, 25);
    //MergeSort object(v); // A tak sortiruet
    printVector(v);
    object.sort();
    printVector(v);
    
    cin.get();
    return 0;
}
 
void fillVector(vector<int> &v, int size)
{
    srand( time(NULL) );
    for(int i=0; i < size; i++) 
        v.push_back( rand()%99 + 1);
}
 
void printVector(const vector<int> &v)
{
    for(int i=0; i < v.size(); i++)
        cout << v[i] << " ";
    cout << endl;
}
И сам класс:
MergeSort.h
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
#ifndef MERGESORT_H
#define MERGESORT_H
 
#include <vector>
using std::vector;
 
class MergeSort
{
    public:
        MergeSort(vector<int>&);
        ~MergeSort();
        
        void sort();
        
    private:
        vector<int> *v;
        vector<int> temp;
        int size;
 
        void merge(int, int, int, int);
        void sortSubVector(int, int);
};
 
#endif
И MergeSort.cpp
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
#include "MergeSort.h"
 
#include <iostream>
using std::cout;
using std::endl;
using std::cin;
 
#include <vector>
using std::vector;
 
MergeSort::MergeSort(vector<int> &vect)
:temp(vect.size())
{
    v = &vect;
    size = vect.size();
}
 
MergeSort::~MergeSort()
{
}
        
void MergeSort::sort()
{
    sortSubVector(0, size-1);
}
 
void MergeSort::sortSubVector(int low, int high)
{
    if( (high-low) >= 1)
    {
        int middle1 = (low + high)/2;
        int middle2 = middle1 + 1;
 
        sortSubVector(low, middle1);
        sortSubVector(middle2, high);
 
        merge(low, middle1, middle2, high);
    }
}
 
void MergeSort::merge(int low, int middle1, int middle2, int high)
{
    int leftIndex = low;
    int rightIndex = middle2; 
    int combInedindex = low;
 
    while( leftIndex <= middle1 && rightIndex <= high)
    {
        if( *(v->begin() + leftIndex) <= *(v->begin() + rightIndex) )
            temp[ combInedindex++ ] = *(v->begin() + leftIndex++);
        else
            temp[ combInedindex++ ] = *(v->begin() + rightIndex++);
    }
 
    if( leftIndex == middle2)
        while( rightIndex <= high)
            temp[ combInedindex++ ] = *(v->begin() + rightIndex++);
    else
        while( leftIndex <= middle1)
            temp[ combInedindex++ ] = *(v->begin() + leftIndex++);
 
    for(int i = low; i <= high; i++)
        *(v->begin() + i) = temp[ i ];
}
Добавлено через 6 минут
Описался в названии темы. Не в файл, а в класс конечно)
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
01.03.2014, 17:37
Ответы с готовыми решениями:

Как правильно передать указатель на структуру, и правильно ее использовать
Я планирую сделать сортировку, но компилятор начал ругаться &quot;Нет существует подходящей функции...

Недопустимый неполный тип , или как передать в функцию указатель на объект класса , или просто объект
Други мои , кодеры. Не могу я ни как передать в функцию объект класса , или что еще лучше(для меня...

Не знаю как правильно передать указатель
В общем для начала приложу код ( не пугайтесь , что придется много читать , из этого кода изучить...

Как правильно передать массив через указатель?
#pragma once #include &lt;vector&gt; class TOMathModel { public: TOMathModel(void);...

8
Эксперт по математике/физикеЭксперт С++
1942 / 1280 / 367
Регистрация: 16.05.2013
Сообщений: 3,339
Записей в блоге: 6
01.03.2014, 18:18 2
Мне кажется дело в том, что вы упутили один момент. При заполнении вектора его адрес может поменяться. Поэтому прежде чем сортировать измененный вектор убедитесь, что в объект v передан обновленный указатель на вектор.

Не по теме:

using объявления лучше писать после всех инклайдов.



Добавлено через 6 минут
Правка:
в объект v
в объект object
0
1 / 1 / 1
Регистрация: 11.11.2012
Сообщений: 23
01.03.2014, 18:28  [ТС] 3
Я так тоже сначала подумал, и сравнил на всех этапах &v и v(элемент данных-указатель на вектор). Но нет, везде адрес одинаковый.
0
Эксперт по математике/физикеЭксперт С++
1942 / 1280 / 367
Регистрация: 16.05.2013
Сообщений: 3,339
Записей в блоге: 6
01.03.2014, 18:35 4
Но это очевидно же:
C++
1
2
3
4
5
    vector<int> v;//Создаем вектор
 
    MergeSort object(v); // Передаем указатель на вектор
    fillVector(v, 25);//Заполняем. Внимание адрес вектора изменился
    //MergeSort object(v); // Здесь передается указатель на уже заплоненный вектор
Впринципе решение довольно простое - зарезервируйте достаточное количество памяти, что бы адрес вектора не поменялся.
Можно так:
C++
1
2
3
    vector<int> v;
v.reserve(4 * 25);
    MergeSort object(v);
Или так
C++
1
    vector<int> v( 4 * 25);
Я взял для примера 100 однако можно и 25..
1
1 / 1 / 1
Регистрация: 11.11.2012
Сообщений: 23
01.03.2014, 18:48  [ТС] 5
Хм... Да, так работает, хотя если сделать вот так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int main()
{
    vector<int> v;
 
    cout << &v << endl;
 
    MergeSort object(v);
    fillVector(v, 25);
    printVector(v);
    object.sort();
    printVector(v);
    
    cout << &v << endl;
 
    cin.get();
    return 0;
}
То окажется, что адреса одинаковые. Но в любом случае, интересно было бы узнать возможно или не возможно сделать то что я хочу(закрепить за объектом вектор, навсегда), и если возможно, то как?
0
Эксперт по математике/физикеЭксперт С++
1942 / 1280 / 367
Регистрация: 16.05.2013
Сообщений: 3,339
Записей в блоге: 6
01.03.2014, 19:03 6
Вы должно быть не до конца поняли. Адрес вектора это не адрес блока памяти выделенного внутри вектора для хранения данных. Вот так должно быть понятнее:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <vector>
#include <iostream>
using std::vector;
 
 
int main()
{
    system("chcp 1251>0");
    vector<int> v;
    v.push_back(11);
    std::cout << "Адрес вектора: "<< &v << std::endl;
    std::cout << "Адрес первого элемента: "<< &v[0] << std::endl;
 
    v.push_back(22);
    v.push_back(33);
    v.push_back(44);
 
    std::cout << "Адрес вектора: "<< &v << std::endl;
    std::cout << "Адрес первого элемента: "<< &v[0] << std::endl;
 
    return 0;
}

Хотя я сам начинаю сомниваться правильно ли я понял задачу
0
1 / 1 / 1
Регистрация: 11.11.2012
Сообщений: 23
01.03.2014, 19:42  [ТС] 7
Ну в общем то, что я хочу, это каким-либо образом всегда иметь возможность обратиться к вектору, если это возможно.
0
Эксперт по математике/физикеЭксперт С++
1942 / 1280 / 367
Регистрация: 16.05.2013
Сообщений: 3,339
Записей в блоге: 6
03.03.2014, 08:41 8
Лучший ответ Сообщение было отмечено pihta как решение

Решение

Оказывается все довольно просто. После заполненя вектора вы не изменяете поле size своего объекта. Рекомендую везде где эта переменная встречается заменить ее на метод вектора:
C++
1
v->size();
А если быть точнее то здесь:
C++
1
2
3
4
void MergeSort::sort()
{
    sortSubVector(0, v->size()-1);
}
1
1 / 1 / 1
Регистрация: 11.11.2012
Сообщений: 23
03.03.2014, 18:17  [ТС] 9
Боже мой, действительно!!!
Ilot Огромное вам спасибо, что помогли!
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
03.03.2014, 18:17

Как правильно передать указатель this в сторонний класс?
Вот файлы: // Field.cpp #include &quot;Field.hpp&quot; Field::Field(void) { attacked = 0; ...

Работа с файлом (передать указатель на файл в функцию, вернуть указатель на файл из функции)
Подскажите как передать указатель на файл в функцию, как вернуть указатель на файл из функции. ...

Как правильно передать и получить указатель из нативной библиотеки?
Есть некий Сишный код (я опускаю __delc и прочее) с C# я абсолютно не знаком struct Block...

Как правильно передать в функцию указатель на двумерный массив?
Сабж #include &lt;windows.h&gt; #include &lt;stdio.h&gt; using namespace std; //ОТ безысходности сделал...


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

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

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