Форум программистов, компьютерный форум CyberForum.ru

Ошибка в конструкторе копирования - C++

Восстановить пароль Регистрация
 
vruleb
0 / 0 / 0
Регистрация: 26.05.2012
Сообщений: 17
03.05.2013, 09:57     Ошибка в конструкторе копирования #1
Здравствуйте. Есть один класс для работы с многочленами, который хранит элементы многочлена в списке. Так вот, в конструкторе копирования (строка 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
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#include <iostream>
 
using namespace std;
 
class Pol{
public:
   class Element{                     
   private: 
      int *data; // элемент многочлена
   public: 
      Element *next; // следующий элемент
      Element *prev; // предыдущий
      Element():next(NULL),prev(NULL){data=new int(0);}; // конструктор по-умолчанию
      Element(int val):next(NULL),prev(NULL){data=new int(val);}; // перегруженный конструктор
      Element (Element &e)      // конструктор копирования
      {
         data=new int(e.getData());
         next=e.next;
         prev=e.prev;
      }
      ~Element(){if (data) delete data;next=prev=NULL;}  // деструктор
 
      int getData(){return *data;}  // метод для получения
      void setData(int val){*data=val;} // и установки данных
   };
   public: 
   Element *first; // первый элемент
   Element *last; // последний
   Pol(Pol &e)  // конструктор копирования
   {
       Pol *z=new Pol();
       Element *i=e.first;  // указатель на первый элемент входного многочлена
       while(i)
       {
           cout << i->getData();
           Add(i->getData());  // добавить все элементы в многочлен
           i=i->next;
       }
   }
   Pol():first(NULL),last(NULL){} 
   Pol operator *()
   {
       return *this;
   }
   virtual ~Pol() // деструктор списка
   {
      Element *p=last;
      while(p)
      {
         Element *pt=p;
         p=p->prev;  
         delete pt; // удаление элементов с конца
      }
      first=last=NULL; // и указателей
   } 
protected:
   void coreAdd(int val)
   {
      Element *t=new Element(val); // создать новый элемент с содержимым val
      if(first==NULL)   // если элементов нет
      {
         first=last=t; // то он первый и последний
         first->next=last->next=NULL; 
         first->prev=last->prev=NULL;
         return; 
      }
      // если есть элементы
      last->next=t; // добавляем после последнего
      t->prev=last; // бывший последний теперь предпоследний
      last=t; // последний - новый элемент
      last->next=NULL;
      return;
   }
   void coreDelete(int n)  
   {
      // поиск выбранного элемента
      if (n<=0)
          cout << "Элемент не найден\n";
      n--; 
      Element *i = first;
      int k=0;
      while (i && k<n)
      {
         i = i->next;
         k++;
      }
 
      if (i)
      {
          i->setData(0); // занулить коэффициент
          if (i==last)  // если занулённый коэффициент - последний коэффициент при многочлене
              while(i->prev!=NULL && i->getData()==0)            // то удалить все нулевые элементы позади
              {
                  Element *t = new Element(*last);
                  last=last->prev;
                  last->next=NULL;
                  delete t;
                  i=i->prev;
              }
      }
   }
public:
   // добавление в конец списка
   virtual void Add(int val) 
   {
      coreAdd(val);
   }
   // удаление элемента
   virtual void Delete(int n)  
   {
      coreDelete(n);
   }
   // вывод многочлена
   friend ostream &operator<<( ostream &output, const Pol &elem)
   {
      int g, h=0;
      Element *i=elem.first;
      cout << endl;
      while (i) // пока есть элементы
      {
        g=i->getData();
        if (g < 0)    // Если коэффициент - отрицательное число
        {                    
        if (h==0)
         cout << g;
        else
            cout << g << "x^" << h; 
        h++;
        }
        if (g==0)
        {
            h++; cout << "+0";
        }
        if (g > 0)
        {
         if (h==0)
             cout << "+" << g;
         else 
             cout << "+" << g << "x^" << h;
         h++;
        }
            i=i->next; // в направлении --->>> 
      }
      return output;
   }
   };
 
void test(Pol a)
{
    Pol c=a;
}
 
int main()
{
    int h=2, l=67;
    Pol b, k; // создать два объекта класса Pol
    b.Add(566); b.Add(453); // заполнить их
    cout << b;
    test(b);
    getchar();
}
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
03.05.2013, 16:36     Ошибка в конструкторе копирования #2
vruleb, стандартные классы использовать нельзя? 32 строка, кстати, лишняя.
abit
 Аватар для abit
260 / 259 / 33
Регистрация: 03.02.2013
Сообщений: 709
03.05.2013, 16:41     Ошибка в конструкторе копирования #3
oO
C++
1
2
3
4
5
6
7
8
9
10
Pol(Pol &e)  // конструктор копирования
   {
       Pol *z=new Pol();
       Element *i=e.first;  // указатель на первый элемент входного многочлена
       while(i)
       {
           cout << i->getData();
           Add(i->getData());  // добавить все элементы в многочлен
           i=i->next;
       }
копайте в теорию c начала, мой мозг отказался это вообще понимать

Pol *z=new Pol();
тут вы выделяете память для Pol, в адресе z, в конструкторе этот адрес не используете, по выходу из конструктора z как указатель помирает, память остаётся, непонятно зачем

далее

C++
1
Add(i->getData());
вообще шикарно, вы хотели прибавить к адресу функции getData() единицу что ли? дело в том, что как выполнится i->getData() она вернёт вам число в поле *(i->data) и никакой связи с полем иметь не будет

если эти измышления описать в более-менее логичном формате должно быть что-то типа такого
C++
1
2
3
4
5
6
7
8
9
10
11
Pol(Pol &e)
   {
       this->first = new Element;
       this->last = new Element;
       Element *i = this->first;
       while (i)
       {
             i->setData(i->getData()+1);
             i=i->next;
       }
   }
но опять же тут надо вникать в логику программы, чтобы знать что и куда копировать, а я всё больше вникаю в ваш конструктор копирования

Что самое странное, метод для добавления новых элементов многочлена работает нормально
ничего странного, там не вызывается конструктор копирования, вызывается впервые он у вас при передачи параметра b в функцию test, чтобы создать локальную копию Pol для внутренностей функции test
vruleb
0 / 0 / 0
Регистрация: 26.05.2012
Сообщений: 17
03.05.2013, 17:38  [ТС]     Ошибка в конструкторе копирования #4
Цитата Сообщение от Tulosba Посмотреть сообщение
vruleb, стандартные классы использовать нельзя? 32 строка, кстати, лишняя.
Цитата Сообщение от abit Посмотреть сообщение
oO
C++
1
2
3
4
5
6
7
8
9
10
Pol(Pol &e)  // конструктор копирования
   {
       Pol *z=new Pol();
       Element *i=e.first;  // указатель на первый элемент входного многочлена
       while(i)
       {
           cout << i->getData();
           Add(i->getData());  // добавить все элементы в многочлен
           i=i->next;
       }
копайте в теорию c начала, мой мозг отказался это вообще понимать


тут вы выделяете память для Pol, в адресе z, в конструкторе этот адрес не используете, по выходу из конструктора z как указатель помирает, память остаётся, непонятно зачем

далее

C++
1
Add(i->getData());
вообще шикарно, вы хотели прибавить к адресу функции getData() единицу что ли? дело в том, что как выполнится i->getData() она вернёт вам число в поле *(i->data) и никакой связи с полем иметь не будет

если эти измышления описать в более-менее логичном формате должно быть что-то типа такого
C++
1
2
3
4
5
6
7
8
9
10
11
Pol(Pol &e)
   {
       this->first = new Element;
       this->last = new Element;
       Element *i = this->first;
       while (i)
       {
             i->setData(i->getData()+1);
             i=i->next;
       }
   }
но опять же тут надо вникать в логику программы, чтобы знать что и куда копировать, а я всё больше вникаю в ваш конструктор копирования



ничего странного, там не вызывается конструктор копирования, вызывается впервые он у вас при передачи параметра b в функцию test, чтобы создать локальную копию Pol для внутренностей функции test
Да, действительно, строка Pol *z=new Pol() лишняя, забыл удалить её после экспериментов с этим конструктором.
Стандартные классы, к сожалению, использовать нельзя.
По логике, мой конструктор должен поэлементно добавлять элементы в новый объект с помощью функции Add(). А функция i->getData() же получает значения элементов копируемого объекта и добавляет в новый.
Yandex
Объявления
03.05.2013, 17:38     Ошибка в конструкторе копирования
Ответ Создать тему
Опции темы

Текущее время: 09:15. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru