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

Конструктор копирования - C++

Восстановить пароль Регистрация
 
 
Scatten
0 / 0 / 0
Регистрация: 28.04.2013
Сообщений: 50
28.06.2013, 10:52     Конструктор копирования #1
Подскажите пожалуйста в моём случае конструктор копирования правильно реализован?

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
class Massiv
{
private:
 
      float *a;
      int n;
 
public:
 
      Massiv(int x)
      { n = x;
        a = new float[n];
      }
 
      virtual ~Massiv()
      {
          delete a;
      }
 
      Massiv(const Massiv& Copy)
      {
          this->n = Copy.n;
          this->a = new float[Copy.n];
      }
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Khelleos
37 / 37 / 7
Регистрация: 13.05.2010
Сообщений: 283
Записей в блоге: 1
28.06.2013, 11:37     Конструктор копирования #2
Нужно ещё скопировать данные из одного массива (Copy.a) в другой (a).
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
28.06.2013, 11:43     Конструктор копирования #3
@Scatten, при удалении массива надо вызывать delete[]. А еще, ознакомьтесь с "правилом трех".
Гром
 Аватар для Гром
199 / 118 / 10
Регистрация: 20.03.2009
Сообщений: 1,075
Записей в блоге: 15
28.06.2013, 13:33     Конструктор копирования #4
Еще несколько небольших замечаний:
1. В конструкторе с int-ом я бы еще произвел инициализацию объектов нулями.
2. Обычно для чисел с плавающей точкой используют double, а не float.
3. В конструкторах лучше использовать список инициализации (хотя в данном случае это некритично):
C++
1
2
3
4
5
6
Massiv::Massiv(int x):
 n(x), a(new double[n])
 {
 for (int i = 0; i < n; ++i)
  a[i] = 0;
 }
4. В конструкторе копирования использование this излишне. Можно обойтись просто
C++
1
2
3
4
5
6
Massiv::Massiv(const Massiv& M):
 n(M.n), a(new double[n])
 {
 for (int i = 0; i < n; ++i)
  a[i] = M.a[i];
 }
или, как у вас
C++
1
2
3
4
5
      Massiv(const Massiv& Copy)
      {
          n = Copy.n;
          a = new float[Copy.n];
      }
(плюс все вышесказанное в этой теме)
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
28.06.2013, 13:46     Конструктор копирования #5
Цитата Сообщение от Гром Посмотреть сообщение
В конструкторе с int-ом я бы еще произвел инициализацию объектов нулями.
Не помешает так же сделать его excplicit
Цитата Сообщение от Гром Посмотреть сообщение
В конструкторах лучше использовать список инициализации
Только вот не стоит забывать в каком порядке будет идти инициализация. А идти она будет в том порядке, в котором объявлены члены в классе. Т.е. сначала выполнится a(new double[n]), а потом n(x). Видите проблему?
Scatten
0 / 0 / 0
Регистрация: 28.04.2013
Сообщений: 50
28.06.2013, 14:19  [ТС]     Конструктор копирования #6
Вот так?

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
Massiv(int x)
      { 
        n = x;
        a = new double[n];
        for (int i = 0; i < n; i++)
                    {
            a[i] = 1;
                    }
      }
 
      virtual ~Massiv()
      {
          delete[] a;
      }
 
      Massiv(const Massiv& Copy)
      {
          n = Copy.n;
          a = new double[Copy.n];
      }
      
      Massiv& operator=(const Massiv& App)
      {
          if (this != &App)
          {
        double *b = new double[App.n];
              copy(App.a, App.a + App.n, b);
              delete []a;
              a = b;
              n = App.n;
          }
          return *this;
      }
BumerangSP
 Аватар для BumerangSP
4283 / 1405 / 121
Регистрация: 16.12.2010
Сообщений: 2,941
Записей в блоге: 3
28.06.2013, 14:22     Конструктор копирования #7
@Tulosba, кстати, студия и на такие вещи ругается:
C++
1
A(int x): n(x), a(new int[n]) {}
Т.е. n на момент передачи размера в new еще как бы не инициализирована
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
28.06.2013, 14:27     Конструктор копирования #8
Цитата Сообщение от BumerangSP Посмотреть сообщение
студия и на такие вещи ругается
И правильно делает. Нормальный компилятор должен об этом сообщать.
Khelleos
37 / 37 / 7
Регистрация: 13.05.2010
Сообщений: 283
Записей в блоге: 1
28.06.2013, 14:32     Конструктор копирования #9
1ый конструктор: лучше обнулять и будет достаточно так написать
C++
1
a = {0};
Для 2го лучше так
C++
1
2
3
4
5
6
7
Massiv(const Massiv& Copy)
{
   n = Copy.n;
   a = new double[Copy.n];
   for(int i = 0; i < n; i++)
      a[i] = Copy.a[i];
}
BumerangSP
 Аватар для BumerangSP
4283 / 1405 / 121
Регистрация: 16.12.2010
Сообщений: 2,941
Записей в блоге: 3
28.06.2013, 14:43     Конструктор копирования #10
@Tulosba, т.е. она на тот момент не инициализирует n, а другие инициализируют. Что в этом правильного?
Scatten
0 / 0 / 0
Регистрация: 28.04.2013
Сообщений: 50
28.06.2013, 14:45  [ТС]     Конструктор копирования #11
У меня не копирует и не присваивает. Массив из нулей постоянно выдаёт.
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
28.06.2013, 14:53     Конструктор копирования #12
@BumerangSP, правильно, что ругается. А не то, что не инициализирует. Инициализация идёт в порядке следования членов в классе.
BumerangSP
 Аватар для BumerangSP
4283 / 1405 / 121
Регистрация: 16.12.2010
Сообщений: 2,941
Записей в блоге: 3
28.06.2013, 14:59     Конструктор копирования #13
@Tulosba, и все равно, странное несоответствие, источник проблем, имхо)
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
28.06.2013, 15:02     Конструктор копирования #14
@BumerangSP, не понял. В чем несоответствие?
BumerangSP
 Аватар для BumerangSP
4283 / 1405 / 121
Регистрация: 16.12.2010
Сообщений: 2,941
Записей в блоге: 3
28.06.2013, 15:06     Конструктор копирования #15
@Tulosba, здесь все нормально компилируется https://ideone.com/YLffjm
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
28.06.2013, 15:15     Конструктор копирования #16
@BumerangSP, а если посмотреть сколько памяти выделится.
https://ideone.com/XtbyYq
BumerangSP
 Аватар для BumerangSP
4283 / 1405 / 121
Регистрация: 16.12.2010
Сообщений: 2,941
Записей в блоге: 3
28.06.2013, 15:22     Конструктор копирования #17

Не по теме:

@Tulosba, да, я это не смотрел)


Получается, он пишет в неразмеченую память. Все равно косяки какие-то.
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
28.06.2013, 15:32     Конструктор копирования #18
Цитата Сообщение от BumerangSP Посмотреть сообщение
Все равно косяки какие-то.
Конечно. Нельзя писать в память, если ее не выделили
Но это же то же самое, что и:
C++
1
2
3
4
int n;
int* p = new int[n];
n = 100;
cout << "Выделили элементов: " << n;
Добавлено через 4 минуты
Правильное решение будет - задать порядок членов
C++
1
2
    int n;
    int *a;
и опционально (иначе будет ворнинг) поменять порядок в инициализаторе конструктора:
C++
1
 A(int x): n(x), a( alloc(n) )
BumerangSP
 Аватар для BumerangSP
4283 / 1405 / 121
Регистрация: 16.12.2010
Сообщений: 2,941
Записей в блоге: 3
28.06.2013, 15:40     Конструктор копирования #19
@Tulosba, так-то оно так. Но вот почему компилеры (не студийный) промолчали, даже предупреждения не выдав...
Стоп, это ж UB?

UPD: не ideone, gcc тот же (в обновленном dev-cpp).
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.06.2013, 16:03     Конструктор копирования
Еще ссылки по теме:

C++ Не могу правильно сделать конструктор и конструктор копирования и принадлежность точки с заданными координатами треугольнику
Конструктор инициализации, конструктор копирования, деструктор C++
Конструктор копирования C++

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

Или воспользуйтесь поиском по форуму:
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
28.06.2013, 16:03     Конструктор копирования #20
Цитата Сообщение от BumerangSP Посмотреть сообщение
компилеры (не студийный) промолчали
ideone не пишет ворнинги, если нет ошибок. https://ideone.com/6UC49N

Добавлено через 19 минут
Цитата Сообщение от BumerangSP Посмотреть сообщение
gcc тот же
Может ворнинги не включены. У меня с -w1 уже выводит gcc 4.7.2
Yandex
Объявления
28.06.2013, 16:03     Конструктор копирования
Ответ Создать тему
Опции темы

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