7 / 7 / 7
Регистрация: 26.04.2015
Сообщений: 220
1

Конструктор копирования для класса стек

04.08.2017, 11:33. Показов 3478. Ответов 24
Метки нет (Все метки)

Почему не хочет работать конструктор копирования?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
struct Item
    {
        int value;
        Item *next;
    };
 
class Int_stack
{
    Item *ptr_stack;
    void push_in_tail(Item*&, const int new_value);
public:
    Int_stack();
    Int_stack(const Int_stack&);
    ~Int_stack();
    
    void push(const int new_value);
    int pop();
};
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
#include "stack.h"
#define null 0 // у меня почему-то компилятор не определяем не NULL не nullptr, так что будет так.
 
Int_stack::Int_stack():ptr_stack(null){}
 
Int_stack::Int_stack(const Int_stack &parent_stack) : ptr_stack(null)
{
    Item *copy_parent_stack = parent_stack.ptr_stack;
    Item *p_tail_stack = ptr_stack;
    while (copy_parent_stack -> next != null)
    {
        push_in_tail(p_tail_stack, copy_parent_stack -> value);
        copy_parent_stack = copy_parent_stack -> next;
    }
    delete p_tail_stack;
    delete copy_parent_stack;
}
 
Int_stack::~Int_stack()
{
    Item *temp = ptr_stack;
    while (temp != null)
    {
        temp = ptr_stack->next;
        delete ptr_stack;
        ptr_stack = temp;
    }
    delete temp;
}
 
void Int_stack::push(const int new_value)
{
    Item *temp = new Item;
    temp -> value = new_value;
    temp -> next = ptr_stack;
    ptr_stack = temp;
}
 
int Int_stack::pop()
{
    int number = ptr_stack -> value;
    Item *temp = ptr_stack;
    ptr_stack = ptr_stack -> next;
    delete temp;
    return number;
}
 
void Int_stack::push_in_tail(Item* &p_tail, const int new_value)
{
    Item *temp = new Item;
    temp -> value = new_value;
    temp -> next = null;
    p_tail -> next = temp;
    delete temp;
}
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
#include <iostream>
#include "stack.h"
 
 
int main()
{
    Int_stack *my_stack = new Int_stack();
    for(int i = 0; i < 10; i++)
    {
        my_stack -> push(i + 1);
    }
/*  
// если начинаю создавать второй класс с помощью конструктора копирования виснет все
    Int_stack *my_stack2 = new Int_stack(*my_stack);
 
    std::cout << "Stack 2:" << std::endl << std::endl;
    {
        for(int i = 0; i < 10; i++)
        {
            std::cout << my_stack2 -> pop() << std::endl;
        }   
        std::cout << std::endl;
    }
        delete my_stack2;
*/
    std::cout << "Stack 1:" << std::endl << std::endl;
    {
        for(int i = 0; i < 10; i++)
        {
            std::cout << my_stack -> pop() << std::endl;
        }   
        std::cout << std::endl;
    }
    
    delete my_stack;
    system("pause");
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
04.08.2017, 11:33
Ответы с готовыми решениями:

Cделать конструктор по умолчанию и копирования для класса
Вот у меня класс строка: class strg { char *str; int len; public: strg(); strg(const...

Конструктор копирования для класса с указателем на абстрактный класс
Всем привет. Как реализовать конструктор копирования для класса Foo? class Base { public: ...

Конструктор копирования для динамического объекта класса приемника
class first_class { public: first_class(int q) { m_q=q; cout&lt;&lt;&quot;First class say...

Конструктор класса, конструктор копирования запускается не тот который нужен
Есть такой конструктор: Neuron::Neuron(int iType_activation_funk) { this-&gt;iType_act =...

24
2098 / 1619 / 690
Регистрация: 27.07.2012
Сообщений: 4,853
04.08.2017, 12:01 2
Цитата Сообщение от Ruta Посмотреть сообщение
Почему не хочет работать конструктор копирования?
Потому что всё неправильно.

Только 1 пример:
C++
1
2
3
4
5
6
7
8
9
void Int_stack::push_in_tail(Item* &p_tail, const int new_value)
{
    Item *temp = new Item;
    temp -> value = new_value;
    temp -> next = null;
    p_tail -> next = temp; // в функцию передавался null, при обращении будет крэш
    delete temp; // зачем удалять только что созданный объект? он должен храниться в стеке, пока его не извлекут.
    // только потом уже удалять
}
0
7 / 7 / 7
Регистрация: 26.04.2015
Сообщений: 220
04.08.2017, 12:12  [ТС] 3
John Prick,
Цитата Сообщение от John Prick Посмотреть сообщение
delete temp; // зачем удалять только что созданный объект? он должен храниться в стеке, пока его не извлекут.
Это не объект это указатель на объект. Я закидываю его в стек и удаляю указатель на него, чтобы не переполнять память

Добавлено через 8 минут
о и надо же хвост сместить:
C++
1
2
3
4
5
6
7
8
9
void Int_stack::push_in_tail(Item* &p_tail, const int new_value)
{
    Item *temp = new Item;
    temp -> value = new_value;
    temp -> next = null;
    p_tail -> next = temp;
    p_tail = p_tail -> next;
    delete temp;
}
0
Mental handicap
1245 / 623 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
04.08.2017, 12:22 4
Цитата Сообщение от Ruta Посмотреть сообщение
разве нет?
смысл такой(пример):
C++
1
2
3
4
5
6
7
8
9
10
11
Node *Temp = new Node; // создаем узел
Temp->elem = val // записываем в узел то что нам нужно
if(tail == 0) // делаем проверку, равен ли 0 хвост
{
   tail = Temp; // если да, перезаписываем
}
else // иначе
{
  Temp->next = tail; // смещаем хвост, а не делаем его равным 0 как у вас
  tail = Temp;
}
0
7 / 7 / 7
Регистрация: 26.04.2015
Сообщений: 220
04.08.2017, 12:37  [ТС] 5
Azazel-San,
Цитата Сообщение от Azazel-San Посмотреть сообщение
Temp->next = tail; // смещаем хвост, а не делаем его равным 0 как у вас
* tail = Temp;
если я не ошибаюсь, то так получется стек 2 обратный стеку 1 (порядок элементов наоборот будет). или я что-то не понимаю? а надо идентичные два стека

Я пытаюсь реализовать добавление в конец списка
0
2098 / 1619 / 690
Регистрация: 27.07.2012
Сообщений: 4,853
04.08.2017, 13:05 6
Цитата Сообщение от Ruta Посмотреть сообщение
Это не объект это указатель на объект. Я закидываю его в стек и удаляю указатель на него, чтобы не переполнять память
Удаляете вы как раз объект.
C++
1
2
3
4
5
    Item *temp = new Item; // создаётся объект Item, его адрес присваивается указателю temp
    // ...
    delete temp; // удаляется объект, на который указывал temp,
    // сам указатель "удалится" автоматически при выходе из функции,
    // так как был объявлен внутри неё
0
Mental handicap
1245 / 623 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
04.08.2017, 13:09 7
Цитата Сообщение от Ruta Посмотреть сообщение
а надо идентичные два стека
зачем, вы хотите скопировать стек1 в стек2, но у вас, так как вы сделали, это не получится
возможно, вам тогда проще из стека1 доставать его элементы, менять местами и перезаписывать в стек2
0
Любитель чаепитий
3734 / 1793 / 563
Регистрация: 24.08.2014
Сообщений: 5,998
Записей в блоге: 1
04.08.2017, 13:10 8
Цитата Сообщение от Ruta Посмотреть сообщение
удаляю указатель на него
неверно.
удаляете то, что было по адресу указателя.
1
7 / 7 / 7
Регистрация: 26.04.2015
Сообщений: 220
04.08.2017, 13:33  [ТС] 9
GbaLog-,
Цитата Сообщение от GbaLog- Посмотреть сообщение
неверно.
удаляете то, что было по адресу указателя.
опана, действительно. А как удалить указатель? или он сам удалится после того как отработает процедура?
0
Любитель чаепитий
3734 / 1793 / 563
Регистрация: 24.08.2014
Сообщений: 5,998
Записей в блоге: 1
04.08.2017, 14:03 10
Цитата Сообщение от Ruta Посмотреть сообщение
или он сам удалится после того как отработает процедура?
указатель - такой же тип переменной, как и, например, int, и он удалится по выходу из области видимости.
если это не динамически созданный указатель, конечно.
1
7 / 7 / 7
Регистрация: 26.04.2015
Сообщений: 220
04.08.2017, 14:06  [ТС] 11
чутка переделала:
C++
1
2
3
4
5
6
7
8
9
10
11
12
void Int_stack::push_in_tail(Item* &p_tail, const int new_value)
{
    Item *temp = new Item;
    temp -> value = new_value;
    temp -> next = null;
    if(p_tail == null) p_tail = temp;
    else
    {
        p_tail -> next = temp;
        p_tail = p_tail -> next;
    }
}
Azazel-San,
Цитата Сообщение от Azazel-San Посмотреть сообщение
зачем, вы хотите скопировать стек1 в стек2
сказали надо - делаю.
Цитата Сообщение от Azazel-San Посмотреть сообщение
но у вас, так как вы сделали, это не получится
это уже поняла.
Цитата Сообщение от Azazel-San Посмотреть сообщение
возможно, вам тогда проще из стека1 доставать его элементы, менять местами и перезаписывать в стек2
так а почему обычное добавление в конец списка не работает?

Добавлено через 1 минуту
GbaLog-, метод пуш - если я вконце дописываю удаление temp - все ложится, temp сделан динамически, как в таких случаях поступать следует?
0
Любитель чаепитий
3734 / 1793 / 563
Регистрация: 24.08.2014
Сообщений: 5,998
Записей в блоге: 1
04.08.2017, 14:07 12
Цитата Сообщение от Ruta Посмотреть сообщение
метод пуш - если я вконце дописываю удаление temp - все ложится, temp сделан динамически, как в таких случаях поступать следует?
динамически созданный указатель - это Item ** ptr = new Item*;.
при этом ptr удалится при выходе из области видимости, а то, на что он указывал - не удалится и будет утечка памяти, если никто не удалит/заберет во владение этот указатель.
в вашем случае указатель создан автоматически, так что и беспокоиться вам за temp не надо.
1
Mental handicap
1245 / 623 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
04.08.2017, 14:12 13
Цитата Сообщение от Ruta Посмотреть сообщение
if(p_tail == null) p_tail = temp;
ставьте скобки даже если только 1 команда выполняется, вроде и мелочь, но повышает читабельность кода
Цитата Сообщение от Ruta Посмотреть сообщение
так а почему обычное добавление в конец списка не работает?
у вас при извлечении данные будут в обратном порядке, вот вы в стек записали числа 1, 2, 3, 4, 5, а при извлечении из стека будет: 5, 4, 3, 2, 1 так уж работает стек, следовательно при записи в стек2, они буду в таком порядке, а вам надо 1, 2, 3, 4, 5
хотя конечно, при извлечении данные будут удалены из стека1, ну смотря что вам нужно сделать, задание вы так и не озвучили?
0
Любитель чаепитий
3734 / 1793 / 563
Регистрация: 24.08.2014
Сообщений: 5,998
Записей в блоге: 1
04.08.2017, 14:18 14
Цитата Сообщение от Azazel-San Посмотреть сообщение
ставьте скобки даже если только 1 команда выполняется, вроде и мелочь, но повышает читабельность кода
фигня это всё.
если будет на другой строке с отступом, то всё будет норм читаться.

по теме: я бы сделал некое подобие std::vector и под капот запихал бы и оставил бы сам stack с implicit-declaration копирующим конструктором.
куда легче, чем велосипеды придумывать.
0
7 / 7 / 7
Регистрация: 26.04.2015
Сообщений: 220
04.08.2017, 14:35  [ТС] 15
Azazel-San, надо конструктор копирования сделать, да такой чтобы если стек1= 5 4 3 2 1 при вызове стек2(стек1) делал стек2 полной копией стека1, та есть стек2 = 5 4 3 2 1.
методом пуш я всегда в стек пихаю в начало списка, поп я выталкиваю из начала списка.
я себе представляю это следующим образом: конструктор копирования должен добавлять в конец списка, а не в начало и тогда у меня получится, что копирую я стек1 в стек2 в том же порядке, так как выталкивать буду с первого элемента все тем же поп.

Добавлено через 15 минут
Все, нашла ошибку:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Int_stack::Int_stack(const Int_stack &parent_stack) : ptr_stack(null)
{
    Item *copy_parent_stack = parent_stack.ptr_stack;
 
        // ниже две строчки, благодаря которым перестала терять указатель на начало списка
    push_in_tail(ptr_stack, copy_parent_stack->value); 
    copy_parent_stack = copy_parent_stack->next;
    
    Item *p_tail_stack = ptr_stack;
    
    while (copy_parent_stack != null)
    {
        push_in_tail(p_tail_stack, copy_parent_stack->value);
        copy_parent_stack = copy_parent_stack->next;
    }
    delete copy_parent_stack;
}
а тут все верно
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
void Int_stack::push_in_tail(Item* &p_tail, const int new_value)
{
    Item *temp = new Item;
    temp -> value = new_value;
    temp -> next = null;
    if(p_tail == null)
        p_tail = temp;
    else
    {
        p_tail -> next = temp;
        p_tail = p_tail -> next;
    }
}
0
Любитель чаепитий
3734 / 1793 / 563
Регистрация: 24.08.2014
Сообщений: 5,998
Записей в блоге: 1
04.08.2017, 16:20 16
Цитата Сообщение от Ruta Посмотреть сообщение
C++
1
#define null 0 // у меня почему-то компилятор не определяем не NULL не nullptr, так что будет так.
какой у вас компилятор?
0
7 / 7 / 7
Регистрация: 26.04.2015
Сообщений: 220
04.08.2017, 16:32  [ТС] 17
GbaLog-, я наверно не совсем правильно выразилась, это же не компилятор скорее вредничает а блокнот) компилятор GNU g++, а блокнот Geany, он странный немного
0
Любитель чаепитий
3734 / 1793 / 563
Регистрация: 24.08.2014
Сообщений: 5,998
Записей в блоге: 1
04.08.2017, 17:33 18
Цитата Сообщение от Ruta Посмотреть сообщение
я наверно не совсем правильно выразилась, это же не компилятор скорее вредничает а блокнот)
и в чём проблема с nullptr в блокноте?
простейшая реализация стека на мой взгляд

надеюсь, что я ничего не накосячил с памятью, так лень думать.
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include <algorithm>
 
class Array
{
public:
  Array() :
    mSize(0),
    mCapacity(5),
    mPtr(new int[mCapacity])
  {}
  
  Array(const Array & rhs)
  {
    if (this == &rhs)
      return;
    
    realloc(rhs.mPtr, rhs.mSize, rhs.mCapacity);
  }
  
  Array & operator =(const Array & rhs)
  {
    if (this == &rhs)
      return *this;
    
    realloc(rhs.mPtr, rhs.mSize, rhs.mCapacity);
    
    return *this;
  }
  
  ~Array()
  {
    delete [] mPtr;
  }
  
  void push_back(int val)
  {
    if (mSize >= mCapacity)
      realloc(mPtr, mSize, mCapacity * 2);
    
    mPtr[mSize++] = val;
  }
  
  void pop_back()
  { --mSize; }
  
  int back() const
  { return mPtr[mSize - 1]; }
  
  size_t size() const
  { return mSize; }
  
  bool empty() const
  { return mSize == 0; }
  
private:
  void realloc(const int * ptr, size_t size, size_t capacity)
  {
    int * tmp = new int[capacity];
    
    std::copy(ptr, ptr + size, tmp);
    
    delete [] mPtr;
    mPtr      = tmp;
    mSize     = size;
    mCapacity = capacity;
  }
  
  size_t  mSize;
  size_t  mCapacity;
  int *   mPtr;
};
 
class Stack
{
public:
  void push(int val)
  { mArray.push_back(val); }
  
  void pop()
  {  mArray.pop_back(); }
  
  int top() const
  { return mArray.back(); }
  
  bool empty() const
  { return mArray.empty(); }
 
private:
  Array mArray;
};
 
#include <iostream>
 
int main()
{
    Stack s;
    s.push(1);
    s.push(2);
    Stack s2 = s;
    
    std::cout << "Stack 1\n";
    
    while (s.empty() == false)
    {
      std::cout << s.top() << "\n";
      s.pop();
    }
    
    std::cout << "Stack 2\n";
    
    while (s2.empty() == false)
    {
      std::cout << s2.top() << "\n";
      s2.pop();
    }
}
0
7 / 7 / 7
Регистрация: 26.04.2015
Сообщений: 220
04.08.2017, 17:50  [ТС] 19
GbaLog-, не знаю он что-то пишет что это 11 года стандарт и не принимает.
Мне надо было просто отработать перегрузку конструктора копирования и оператора равно, что я и делала
0
Любитель чаепитий
3734 / 1793 / 563
Регистрация: 24.08.2014
Сообщений: 5,998
Записей в блоге: 1
04.08.2017, 19:01 20
Цитата Сообщение от Ruta Посмотреть сообщение
не знаю он что-то пишет что это 11 года стандарт и не принимает.
ну а NULL тут при чём?
в комментарии написано "не NULL не nullptr", NULL - это явно не с++11.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.08.2017, 19:01
Помогаю со студенческими работами здесь

Будет ли утрачена память, когда конструктор копирования вызывается для уже существующего объекта класса?
class A { char * v; A(); ~A(); A(const A &amp;obj); } ///////////////////// A::A() {

Создать конструктор копирования для класса "Прямоугольник"
Всем привет! Помогите разобраться, пожалуйста! Есть такое задание: Определить класс...

Создать конструктор копирования класса
Помогите создать конструктор копирования класса. Мне надо чтоб я в основной программе нажимал...

Конструктор копирования шаблонного класса
Всем доброго времени суток! Язык С++ изучаю относительно недавно и столкнулся с задачей, которую не...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru