С Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
vruleb
0 / 0 / 0
Регистрация: 26.05.2012
Сообщений: 17
#1

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

03.05.2013, 09:57. Просмотров 337. Ответов 3
Метки нет (Все метки)

Здравствуйте. Есть один класс для работы с многочленами, который хранит элементы многочлена в списке. Так вот, в конструкторе копирования (строка 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();
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.05.2013, 09:57
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Ошибка в конструкторе копирования (C++):

Ошибка в конструкторе копирования C++ - C++
Помогите, пожалуйста создать конструктор копирования, который будет копировать элемент и добавлять его в список. У меня получился такой...

Ошибка в конструкторе копирования класса - C++
Хотя и делал по образцу, но почему то лезет ошибка записи за пределы динамического массива, хотя и переменные копируются верно (отладчик...

О конструкторе копирования - C++
Доброго времени суток всем присутствующим. Интересует маленький вопрос. В 15-й строке происходит прямое обращение к полю входного объекта...

Параметр в конструкторе копирования - C++
Есть класс class CMatrix{ valarray&lt;valarray&lt;double&gt; &gt; matrix; public: CMatrix(const CMatrix &amp;M); ..... }; ...

Указатель this в конструкторе копирования - C++
Добрый всем вечер. Подскажите пожалуйста, как правильно применить в конструкторе копирования указатель this? Вот есть код. ...

Зачем нужна ссылка в конструкторе копирования - C++
Вопрос такой, Зачем нужна ссылка в конструкторе копирования? Почему не передавать напр. по указателю?

3
Tulosba
:)
Эксперт С++
4397 / 3233 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
03.05.2013, 16:36 #2
vruleb, стандартные классы использовать нельзя? 32 строка, кстати, лишняя.
0
abit
271 / 270 / 35
Регистрация: 03.02.2013
Сообщений: 760
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
0
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() же получает значения элементов копируемого объекта и добавляет в новый.
0
03.05.2013, 17:38
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.05.2013, 17:38
Привет! Вот еще темы с ответами:

Можно ли в конструкторе копирования поменять один параметр? - C++
Здравствуйте. Мне нужно при создании объекта через конструктор копирования поменять один параметр в конструкторе. Такое можно реализовать?

Ссылка rvalue в конструкторе копирования и операторе присваивания - C++
Здравствуйте. Решил попробовать ссылки rvalue в классе. Привожу часть: \\BinaryArray.h class BinaryArray { protected: ...

Исправить ошибку в конструкторе копирования пользовательского класса Sort - C++
Здравствуйте. Такая вот проблема. Обычный конструктор работает без ошибок и подчеркиваний: Sort::Sort() { cout &lt;&lt; &quot;len = &quot;; ...

С какой целью необходимо передвать по ссылке переменную в конструкторе копирования? - C++
Почему аргумент в конструктор копирования передается не по значению, а по ссылке? Объясните понятным языком, пожалуйста. ...


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

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

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