Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/13: Рейтинг темы: голосов - 13, средняя оценка - 5.00
0 / 0 / 0
Регистрация: 01.04.2015
Сообщений: 27

Вернуть значение из функции, используя shared_ptr

20.02.2018, 04:33. Показов 2910. Ответов 17

Студворк — интернет-сервис помощи студентам
Здравствуйте,
Начал работу с умными указателями и столкнулся с проблемой. У меня есть класс (приведу лишь необходимый кусок кода):
C++ (Qt)
1
2
3
4
5
class LongLong {
private:
    shared_ptr<vector<int>> number = make_shared<vector<int>>();
    int base;
...
В нем реализован метод Sub (Вычитание):
C++ (Qt)
1
void Sub(LongLong B) {}
и Div (Деление):
C++ (Qt)
1
void Div(LongLong B, LongLong& C) {}
В случае Sub, изменяется первое заданное значение (A-B, результат в A), в случае Div, результат сохраняется в C (A/B=C). Теперь суть проблемы: в методе Div я вызываю метод Sub, после которого значение B обнуляется. Как я понял, дело как раз в shared_ptr, который сам освобождает память. Нельзя ли никак вернуть значение после вычитания в функцию деления, чтобы работать с ним дальше?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
20.02.2018, 04:33
Ответы с готовыми решениями:

Как в функции вернуть значение, а потом продолжить работу этой функции?
Есть функция main, которая возвращает определенное значение. Это значение должно вернутся в течении 1.5 секунд. Проблема в том, что в этой...

Как вернуть курсор в функции оракл и вызвать ее в C#, используя интерфейс OLEDB
есть функция оракл, думаю она правильная: create or replace package test_pkg1 is type c1_ref_cursor is ref cursor; function...

Реализовать shared_ptr, используя классы
Необходимо реализовать &quot;умный&quot; указатель shared_ptr, используя классы. 1. Какие классы нужно создать? 2. Какие поля должны быть у...

17
║XLR8║
 Аватар для outoftime
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,360
Записей в блоге: 5
20.02.2018, 04:44
Цитата Сообщение от Rickflar Посмотреть сообщение
приведу лишь необходимый кусок кода
Да, было бы не плохо
Цитата Сообщение от Rickflar Посмотреть сообщение
в методе Div я вызываю метод Sub
привести
0
0 / 0 / 0
Регистрация: 01.04.2015
Сообщений: 27
20.02.2018, 04:47  [ТС]
Кусок Div'a, где вызываю Sub:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
else {
                int c=1;
                while ((c == 1) || (c == 2)) {
                    Sub(B);
                    C.Add(D);
                    if (number->size() < B.number->size()) {
                        for (int i = number->size(); i < B.number->size(); i++) {
                            number->push_back(0);
                        }
                    }
0
║XLR8║
 Аватар для outoftime
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,360
Записей в блоге: 5
20.02.2018, 04:55
Цитата Сообщение от Rickflar Посмотреть сообщение
приведу лишь необходимый кусок
Цитата Сообщение от Rickflar Посмотреть сообщение
Кусок Div'a, где вызываю Sub:
Это не кусок, это огрызок
0
0 / 0 / 0
Регистрация: 01.04.2015
Сообщений: 27
20.02.2018, 05:00  [ТС]
outoftime, окей, весь Div
C++ (Qt)
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
void Div(LongLong B, LongLong& C) {
        C.number->resize(number->size());
        LongLong D;
        D.number->push_back(1);
        int b;
        if (number->size() < B.number->size()) {
            for (int i = number->size(); i < B.number->size(); i++) {
                number->push_back(0);
            }
        }
        else if (number->size() > B.number->size()) {
            for (int i = B.number->size(); i < number->size(); i++) {
                B.number->push_back(0);
            }
        }
        for (size_t i = 0; i < max(number->size(), B.number->size()); i++) {
            if (number->at(i) > B.number->at(i)) {
                b = 1;
            }
            else if (number->at(i) == B.number->at(i)) {
                b = 2;
            }
            else {
                b = -1;
            }
        }
        if (b == -1) {
        }
        else {
            int c=1;
            while ((c == 1) || (c == 2)) {
                Sub(B);
                C.Add(D);
                if (number->size() < B.number->size()) {
                    for (int i = number->size(); i < B.number->size(); i++) {
                        number->push_back(0);
                    }
                }
                else if (number->size() > B.number->size()) {
                    for (int i = B.number->size(); i < number->size(); i++) {
                        B.number->push_back(0);
                    }
                }
                for (size_t i = 0; i < max(number->size(), B.number->size()); i++) {
                    if (number->at(i) > B.number->at(i)) {
                        c = 1;
                    }
                    else if (number->at(i) == B.number->at(i)) {
                        c = 2;
                    }
                    else {
                        c = -1;
                    }
            }
        }
    }
    while (C.number->size() > 1 && C.number->back() == 0) {
        C.number->pop_back();
    }
    }
0
║XLR8║
 Аватар для outoftime
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,360
Записей в блоге: 5
20.02.2018, 05:29
Цитата Сообщение от Rickflar Посмотреть сообщение
max(number->size(), B.number->size())
они равны, в чем прикол?

Добавлено через 1 минуту
Цитата Сообщение от Rickflar Посмотреть сообщение
number->at(i
у тебя счетчик никогда не выходит за границы, зачем эта проверка, ты где-то ловишь это исключение?

Добавлено через 1 минуту
Цитата Сообщение от Rickflar Посмотреть сообщение
if (number->at(i) > B.number->at(i)) {
* * * * * * * * b = 1;
* * * * * * }
* * * * * * else if (number->at(i) == B.number->at(i)) {
* * * * * * * * b = 2;
* * * * * * }
* * * * * * else {
* * * * * * * * b = -1;
* * * * * * }
У тебя запоминается только последнее значение, зачем цикл вообще?
0
0 / 0 / 0
Регистрация: 01.04.2015
Сообщений: 27
20.02.2018, 05:31  [ТС]
outoftime, изначально не были, забыл поправить. Проблема то не в этом, а в том, что после вызова функции Sub, LongLong B обнуляется, понятное дело почему. Интересует можно ли вернуть значение при помощи shared_ptr из функции.

P.S. Исключений нет, number->at(i) указывается на i-ый элемент в векторе.
P.S.S. Цикл для сравнения чисел. дело в том, что я работаю с длинными числами, которые представляю вектором. Поэтому, для их сравнения, провожу проверку циклом.
0
║XLR8║
 Аватар для outoftime
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,360
Записей в блоге: 5
20.02.2018, 05:39
Цитата Сообщение от Rickflar Посмотреть сообщение
Div
плохой подход к именованию, лучше бы операторы перегрузить operator/ , operator/= , operator-, operator-= и т.д. чтобы была разница межу модицикацией объекта на месте и возаращением нового инстанса ну или названия дай чтобы различать эти два случая

Добавлено через 3 минуты
Цитата Сообщение от Rickflar Посмотреть сообщение
Sub(B);
* * * * * * * * C.Add(D);
* * * * * * * * if (number->size() < B.number->size()) {
условие никто не будет истенным number->size() равен B.number->size()

Цитата Сообщение от Rickflar Посмотреть сообщение
if (number->size() < B.number->size()) {
* * * * * * for (int i = number->size(); i < B.number->size(); i++) {
* * * * * * * * number->push_back(0);
* * * * * * }
* * * * }
* * * * else if (number->size() > B.number->size()) {
* * * * * * for (int i = B.number->size(); i < number->size(); i++) {
* * * * * * * * B.number->push_back(0);
* * * * * * }
* * * * }
Добавлено через 2 минуты
Цитата Сообщение от Rickflar Посмотреть сообщение
Интересует можно ли вернуть значение при помощи shared_ptr из функции.
Можно, вопрос зачем.

Судя по тому что ты показал у тебя код вообще ничего неделает, из того что должен по названию метода.
0
0 / 0 / 0
Регистрация: 01.04.2015
Сообщений: 27
20.02.2018, 05:40  [ТС]
outoftime, до применения shared_ptr, код работал оптимально, делил одно на другое, поэтому и хочу знать, как вернуть B, чтобы продолжить вычисления. Остальные замечания учту и поправлю.
0
║XLR8║
 Аватар для outoftime
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,360
Записей в блоге: 5
20.02.2018, 05:45
Цитата Сообщение от Rickflar Посмотреть сообщение
до применения shared_ptr, код работал оптимально, делил одно на другое
Ну так покажи мне код нормальный, что я могу сказать по тому что ты показал? Мне показалось, что я уже высказался. Покажи рабочий код, который был до всей этой лобурды.

И еще, пользуясь моментом PR Как понять rvalue & lvalue в C/C++ (перевод) хорошобы знать это и move семантику, чтобы работать с умными указателями. А тем временем жду рабочий код.
0
0 / 0 / 0
Регистрация: 01.04.2015
Сообщений: 27
20.02.2018, 05:51  [ТС]
outoftime,
C++ (Qt)
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
void Div(LongLong B, LongLong &C) {
        C.number.resize(number.size());
        if (B.number.size() == 1) {
            int carry = 0;
            for (int i = (int)number.size() - 1; i >= 0; --i) {
                long long cur = number[i] + carry * 1ll * base;
                number[i] = int(cur / B.number[0]);
                carry = int(cur % B.number[0]);
            }
            while (number.size() > 1 && number.back() == 0) {
                number.pop_back();
            }
            for (size_t i = 0; i < number.size(); i++) {
                C.number[i] = number[i];
            }
            for (size_t i = 0; i < number.size(); i++) {
                number[i] = 0;
            }
            number[0] = carry;
        }
        else {
            LongLong D;
            D.number.push_back(1);
            int b = Compare(B);
            if (b == -1) {
            }
            else {
                int c = 1;
                while ((c == 1) || (c == 2)) {
                    Sub(B);
                    C.Add(D);
                    c = Compare(B);
                }
            }
        }
    }
Вот так выглядел Div до начала работы с shared_ptr. Если делитель меньше максимального значения (1000000000), то деление осуществлялось первой частью функцию, иначе второй. По факту, я просто отнимал от делимого делитель и считал количество повторений операции. Тем самым получал частное.

Compare - функция сравнения, если что.
0
║XLR8║
 Аватар для outoftime
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,360
Записей в блоге: 5
20.02.2018, 06:01
Цитата Сообщение от Rickflar Посмотреть сообщение
Если делитель меньше максимального значения (1000000000), то деление осуществлялось первой частью функцию, иначе второй.
Первая часть это деление длинного на короткое, его лучше отдельным методом или перегрузкой делать.

Ну ок, этот код понять можно. Теперь вопрос: зачем тебе умные указатели? И так всё хорошо. Модуль сохраниться в this а целая часть в C
0
0 / 0 / 0
Регистрация: 01.04.2015
Сообщений: 27
20.02.2018, 06:03  [ТС]
outoftime, мне по заданию нужно представить вектор, используя shared_ptr (что я сделал), а в соответствии с этим, поправить функции.
За совет спасибо, исправлю
0
║XLR8║
 Аватар для outoftime
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,360
Записей в блоге: 5
20.02.2018, 06:12
Цитата Сообщение от Rickflar Посмотреть сообщение
представить вектор, используя shared_ptr
слушай, а может тебе не вектор надо, а? std::vector это контейнер, который и так управляет памятью, а ты его еще и std::shared_ptr засунуть хочешь. Может тебе обычный массив надо и его уже скармливать std::shared_ptr?

Странное задание, как по мне, смысла нет. Даже если ты засунешь numbers в shared_ptr в чем смысл, у тебя же объект LongLong является владельцем, почему не unique_ptr тогда? И опять таки, shared_ptr используется когда ты хочешь предоставлять права владения в другие места, но ведь LongLong не должен никому показывать что у него внутри, тем более ссылаться напрямую и недай Бог ставить shared_ptr на массив который должен чиститься при вызове деструктора LongLong
0
0 / 0 / 0
Регистрация: 01.04.2015
Сообщений: 27
20.02.2018, 06:19  [ТС]
outoftime, вообще, задание подразумевало использовать умные указатели, без указания конкретных. Считаете, что лучше использовать unique_ptr? Как тогда возвращать значения функций?
0
║XLR8║
 Аватар для outoftime
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,360
Записей в блоге: 5
20.02.2018, 06:27
Цитата Сообщение от Rickflar Посмотреть сообщение
Как тогда возвращать значения функций?
Возвращать объект класса LongLong в котором есть нужные данные. И все эти Div, Compare, Sub реализовать как меторы класса LongLong только опять таки, лучше не их создавать я перегрузки делать операторов

Добавлено через 2 минуты
Rickflar, https://github.com/Limeoats/Bi... ignumber.h не идеально, но почерпнуть есть что

Добавлено через 2 минуты
Rickflar, только там строковое представление, что просто ужасно (:
0
0 / 0 / 0
Регистрация: 01.04.2015
Сообщений: 27
20.02.2018, 06:30  [ТС]
outoftime, у меня в работе числа также строками представляются. Потом уже "отщепляю" нужное мне количество и помещаю в вектор. То есть заменяем void на LongLong и добавляем return?
0
║XLR8║
 Аватар для outoftime
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,360
Записей в блоге: 5
20.02.2018, 07:07
Rickflar,
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
#include <iostream>
#include <algorithm>
#include <memory>
#include <initializer_list>
 
class big
{
    const static int32_t base = 1e9;
    std::unique_ptr<int32_t[]> arr;
    size_t len;
 
  public:
    big(const size_t &size) : len{size}, arr{new int32_t[size]} {}
    big(const big &other) : len{other.len}, arr{new int32_t[other.len]} {
        std::copy(other.arr.get(), other.arr.get() + len, arr.get()); }
    big(big &&other) : len{other.len}, arr{std::move(other.arr)} {}
    big(std::initializer_list<int32_t> list) : len{list.size()}, arr{new int32_t[list.size()]} {
        std::copy(list.begin(), list.end(), arr.get()); }
    big operator+(const big &other) {
        int32_t carry = 0;
        for (int i = 0; i < std::max(len, other.len); ++i)
        {
            int64_t res = carry + (i < len ? arr[i] : 0) + (i < other.len ? other.arr[i] : 0);
            carry = res / base;
        }
        big ans(std::max(other.len, len) + (carry > 0));
        carry = 0;
        for (int i = 0; i < std::max(len, other.len) || carry; ++i)
        {
            int64_t res = carry + (i < len ? arr[i] : 0) + (i < other.len ? other.arr[i] : 0);
            ans.arr[i] = res % base;
            carry = res / base;
        }
        return ans;
    }
    friend std::ostream &operator<<(std::ostream &out, big &value) {
        for (int i = 0; i < value.len; ++i)
            out << value.arr[i];
        return out;
    }
};
 
int main()
{
    big a{1, 2}, b{3, 4};
    big c{a + b};
    std::cout << c << std::endl;
}
Примерно так можно.

Добавлено через 1 минуту
Rickflar, код вышел не очень красивый, но в целом дает понять что к чему, при реализации operator+= надо возвращать ссылку на big& с помощью return *this;

Добавлено через 7 минут
И прочти ту ссылку что я дал, либо еще где-то разберить что такое rvalue и lvalue указатели.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
20.02.2018, 07:07
Помогаю со студенческими работами здесь

Вернуть значение из функции
Приветсвую программисты! Такая проблема, надо возвратить m из функции, а оно возвращает не то что надо вообще 2 ошибки: вот основной...

Вернуть значение рекурсивной функции
Доброго времени суток! function calc($a,$b){ if ($a==0){ echo &quot;inkrement&lt;br&gt;&quot;; $res = $res + 1; } else{ for...

Как из функции вернуть значение
Есть код, нужно сделать так, чтобы в подпрограмме не было append'ов, т.е функция должна только считать значение и возвращать в основную...

Не могу вернуть значение из функции
Код : def setup_profile(name, vacation_dates): # задаём информацию про работника return name, vacation_dates def...

Как вернуть значение функции в С++
Помогите с задачей


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

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru