Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.60/15: Рейтинг темы: голосов - 15, средняя оценка - 4.60
Alvin Seville
 Аватар для Соколиный глаз
343 / 273 / 134
Регистрация: 25.07.2014
Сообщений: 4,537
Записей в блоге: 22

stack_t<T> не компилируется

19.02.2019, 15:55. Показов 3083. Ответов 43
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Вторая попытка. Решил сегодня заняться стеком. Вот что вышло:
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
#include "pch.h"
#include <malloc.h>
#include <iostream>
#include <initializer_list>
#include <exception>
#include <stdexcept>
 
using namespace std;
 
template <typename T>
class stack_t
{
private:
    int DEFAULT_CAPACITY = 4;
 
    T* source;
    int count, capacity;
 
public:
    int get_count()
    {
        return count;
    }
 
    stack_t(initializer_list<T> source)
    {
        for (T item : source)
            push(item);
    }
 
    stack_t()
    {
    }
 
    void push(T item)
    {
        if (count == capacity)
            source = (T*)malloc((capacity = 0 ? DEFAULT_CAPACITY : capacity * 2) * sizeof(T));
        *(source + count) = item;
        count++;
    }
 
    T pop()
    {
        if (count == 0)
            throw new out_of_range();
        int last = count - 1;
        T result = *(source + last);
        *(source + last) = new T();
        return result;
    }
};
 
int main()
{
    stack_t<int>* ptr_s = new stack_t<int>({ 1, 2, 3 });
    cout << ptr_s->pop();
}
При компиляции выдаёт:
1) =: невозможно преобразовать "T *" в "T" - строка 49
2) std::out_of_range::out_of_range: нет подходящего конструктора по умолчанию - строка 46
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
19.02.2019, 15:55
Ответы с готовыми решениями:

Программа компилируется в Borland 6.0 но не компилируется в Visual Studio 2008
Ета програма компилируетса в борланде 6.0 но не компилируетса в Visualstudio 2008 и в борланде 10-м почему? #include&lt;iostream&gt; ...

Компилируется в С++ bulder 6.0 но не компилируется в VS 2010 express
Здравствуйте. есть небольшая программка которая с успехом компилируется в borland C++ builder 6.0 но не в какую не хочет компилироваться...

В формате .cpp код компилируется, а в .c не компилируется
1).Подскажите почему в формате .cpp код компилируется, а в .c не компилируется 2). Как сделать так, чтобы компилировалось в .c? ...

43
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
19.02.2019, 15:58
Цитата Сообщение от Соколиный глаз Посмотреть сообщение
*(source + last) = new T();
наверно звездочка лишняя

Добавлено через 1 минуту
Цитата Сообщение от Соколиный глаз Посмотреть сообщение
new out_of_range();
нужен аргумент string или char*, out_of_range("")
0
Alvin Seville
 Аватар для Соколиный глаз
343 / 273 / 134
Регистрация: 25.07.2014
Сообщений: 4,537
Записей в блоге: 22
19.02.2019, 15:58  [ТС]
Убрал её и:
=: левый операнд должен быть левосторонним значением
0
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
19.02.2019, 15:58
Цитата Сообщение от Соколиный глаз Посмотреть сообщение
new out_of_range();
нужен аргумент string или char*, out_of_range("")
1
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
19.02.2019, 16:01
Цитата Сообщение от Соколиный глаз Посмотреть сообщение
Убрал её и:
да, source + last дает временный объект (rvalue), наверно стоит поменять логику в коде?
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
19.02.2019, 16:01
Соколиный глаз, шас бы маллок и new вместе использовать в С++ в 2019 году..
1
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
19.02.2019, 16:03
---
0
Alvin Seville
 Аватар для Соколиный глаз
343 / 273 / 134
Регистрация: 25.07.2014
Сообщений: 4,537
Записей в блоге: 22
19.02.2019, 16:04  [ТС]
Azazel-San, варианты? Я новичок в C++, если поможете, буду благодарен.

Добавлено через 59 секунд
_stanislav, а на что поменять логику?
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
19.02.2019, 16:04
Цитата Сообщение от Соколиный глаз Посмотреть сообщение
если поможете
Давайте подумаем что должен делать pop в стеке, а потом перейдем к написанию кода?
0
Alvin Seville
 Аватар для Соколиный глаз
343 / 273 / 134
Регистрация: 25.07.2014
Сообщений: 4,537
Записей в блоге: 22
19.02.2019, 16:05  [ТС]
Azazel-San, должен извлекать элемент на вершине стека, а также обнулять освободившееся место.
0
3258 / 2060 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
19.02.2019, 16:10
Цитата Сообщение от Соколиный глаз Посмотреть сообщение
варианты? Я новичок в C++, если поможете, буду благодарен.
Для выделения памяти — operator new, для конструирования объекта в выделенной памяти — placement new.
1
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
19.02.2019, 16:12
Цитата Сообщение от _stanislav Посмотреть сообщение
source + last дает временный объект (rvalue)
но *(source + last) - lvalue
Цитата Сообщение от Соколиный глаз Посмотреть сообщение
должен извлекать элемент на вершине стека
А зчем вы пытаетесь там память выделять через new?
1
Alvin Seville
 Аватар для Соколиный глаз
343 / 273 / 134
Регистрация: 25.07.2014
Сообщений: 4,537
Записей в блоге: 22
19.02.2019, 16:15  [ТС]
Azazel-San, ну, я хочу занулить освободившееся место. Если там была ссылка на объект, то она без очистки будет так и висеть, пока новый элемент её не сменит. Для решения этой проблемы в C# я написал такой код:
C#
1
2
3
4
5
6
7
        public T Pop()
        {
            ThrowIfEmpty();
            T result = source[--Count];
            source[Count] = default(T); // <-- Все, теперь этот удалённый элемент имеет значение по умолчанию для T.
            return result;
        }
В C++ я попытался сделать тоже самое.
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
19.02.2019, 16:18
Цитата Сообщение от Соколиный глаз Посмотреть сообщение
В C++ я попытался сделать тоже самое.
new - выделит новый участок в памяти, а старый навсегда утеряется, имеем утечку памяти.
1
Alvin Seville
 Аватар для Соколиный глаз
343 / 273 / 134
Регистрация: 25.07.2014
Сообщений: 4,537
Записей в блоге: 22
19.02.2019, 16:19  [ТС]
Azazel-San, а как мне тогда установить значение по умолчанию для удалённого элемента стека типа T?
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
19.02.2019, 16:22
Соколиный глаз, зачем вам динамика уже, я вижу вы стек хотите сделать на массиве, начните с обычного)

Добавлено через 3 минуты
Цитата Сообщение от Соколиный глаз Посмотреть сообщение
а как мне тогда установить значение по умолчанию для удалённого элемента стека типа T?
Это не столь важно, можно просто размер массива уменшать на 1, при извлечении, это если брать статический массив.
1
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
19.02.2019, 16:29
Цитата Сообщение от Соколиный глаз Посмотреть сообщение
а как мне тогда установить значение по умолчанию для удалённого элемента стека типа T?
Цитата Сообщение от Azazel-San Посмотреть сообщение
можно просто размер массива уменшать на 1
Хотя в вашем случае наверное тоже можно так сделать)
C++
1
2
3
4
5
6
7
T pop()
{
    if (count == 0)
        throw new out_of_range();
 
    return source[--count];
}
Если все верно понял что-то типа такого (не тестил)
0
Alvin Seville
 Аватар для Соколиный глаз
343 / 273 / 134
Регистрация: 25.07.2014
Сообщений: 4,537
Записей в блоге: 22
19.02.2019, 16:30  [ТС]
Хорошо.

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
#include "pch.h"
#include <malloc.h>
#include <iostream>
#include <initializer_list>
#include <exception>
#include <stdexcept>
#include <array>
 
using namespace std;
 
template <typename T>
class stack_t
{
private:
    array<T, 1000> source;
    int count, capacity;
 
public:
    int get_count()
    {
        return count;
    }
 
    stack_t(initializer_list<T> source)
    {
        for (T item : source)
            push(item);
    }
 
    stack_t()
    {
    }
 
    void push(T item)
    {
        source[count] = item;
        count++;
    }
 
    T pop()
    {
        if (count == 0)
            throw new out_of_range("count было 0");
        return source[--count];
    }
};
 
int main()
{
    stack_t<int>* ptr_s = new stack_t<int>({ 1, 2, 3 });
    cout << ptr_s->pop();
}
Выдаёт array subscript out of range.
0
3258 / 2060 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
19.02.2019, 16:32
Лучший ответ Сообщение было отмечено Соколиный глаз как решение

Решение

Цитата Сообщение от Соколиный глаз Посмотреть сообщение
а как мне тогда установить значение по умолчанию для удалённого элемента стека типа T?
Что вы понимаете под значением по умолчанию для типа T? Единственное, что мне приходит в голову при такой формулировке — это значение, полученное при конструировании объекта с помощью дефолтного конструктора. Это противоречит идеологии C++ — не платить за то, что не используешь. Конструктор может выполнять нетривиальную работу, захватывать ресурсы, и т. д. По задаче нужно избавиться от объекта на вершине стека, а не заменять его дефолтным.

В С# ситуация другая. Для ссылочных типов значением по умолчанию будет null, что в C++ сделать, конечно, можно, но потребует дополнительных накладных расходов во время выполнения. Не нужно пытаться полностью перенести модель C# в C++.

Ваше решение осложняет задачу тем, что у вас разделены процессы выделения памяти (выделяем пул заранее) и конструирования объектов. Задача была бы проще, если бы в качестве хранилища вы использовали список. Но такое решение может оказаться менее производительным.

Если же мы решили выделять буфер заданной емкости, то нужно следить за такими вещами:

1. Для выделения буфера использовать operator new. Он выделит память, но не вызовет конструктор T.
2. Для конструирования объектов использовать placement new. Он использует уже выделенную память и только вызывает конструктор. С момента вызова конструктора начинается время жизни объекта.
3. При извлечении элемента нужно вручную вызвать деструктор. Только после этого в том же участке памяти можно конструировать другой объект с помощью placement new.

Добавлено через 1 минуту
Цитата Сообщение от Соколиный глаз Посмотреть сообщение
Выдаёт array subscript out of range.
Поля count и capacity неинициализированы.
1
Alvin Seville
 Аватар для Соколиный глаз
343 / 273 / 134
Регистрация: 25.07.2014
Сообщений: 4,537
Записей в блоге: 22
19.02.2019, 16:35  [ТС]
Цитата Сообщение от 0x10 Посмотреть сообщение
Что вы понимаете под значением по умолчанию для типа T?
Вот для int - 0, для ссылочных типов - нулевая ссылка (null в С#, nullptr - C++, как помню).

Добавлено через 2 минуты
Заработало! Счастье то какое.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
19.02.2019, 16:35
Помогаю со студенческими работами здесь

Заголовочный файл, который компилируется в VS2017, не компилируется в Qt
В общем был класс &quot;Матрицы&quot;, который нормально работал в VS2017. Возникла необходимость использовать использовать его для создания...

Не компилируется
Выдает ошибку 'undefined reference to 'WinMain@16' ' Не могу исправить...срочно нужна помощь #include&lt;iostream&gt; using...

Не компилируется
create table client( id SERIAL PRIMARY KEY, full_name VARCHAR(40) NOT NULL, phone_number VARCHAR(20) NOT NULL, card_type...

Не компилируется!!!!
Написал прогу которая каждое слово записывает в массив. При вводе текста выбивает объявления, а именно &quot;Инструкция по адресу...

Не компилируется
При нажатии build/compile пишет visual studio has encountered an unexpected error Как это исправить? Только начинаю изучать, а уже...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США. Нашел на реддите интересную статью под названием «Кто-нибудь знает, где получить бесплатный компьютер или. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru