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

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

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 15, средняя оценка - 5.00
ramarren14
2 / 2 / 0
Регистрация: 14.07.2011
Сообщений: 49
17.08.2011, 14:03     Конструктор копировщик #1
Самостоятельно изучаю С++ по Либерти(освой за 21 день)
Требуется создать класс и конструктор копировщик. Компилятор Visual C++ 2010.
Выдает ошибку:
1>c:\users\selver\documents\visual studio 2010\projects\bufer\bufer\hgfh.cpp(42): error C2662: 'SimpleCircle::GetRadius' : cannot convert 'this' pointer from 'const SimpleCircle' to 'SimpleCircle &'

Хотя в книге написано что должно работать.
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
#include<iostream>
using namespace std;
 
class SimpleCircle{
public:
    SimpleCircle();
    ~SimpleCircle();
    SimpleCircle (const SimpleCircle &);
    int GetRadius (){return *itsRad;}
    void SetRadius(int x){*itsRad=x;}
    
private:
    int *itsRad;
};
 
SimpleCircle::SimpleCircle(){
    itsRad=new int;
    *itsRad=10;
}
 
 
 
 
SimpleCircle::~SimpleCircle(){
    delete itsRad;
    itsRad=0;
}
 
SimpleCircle::SimpleCircle (const SimpleCircle & rhs){
    itsRad=new int;
    *itsRad=rhs.GetRadius();
}
 
 
int main(){
    SimpleCircle Circl_one;
    SimpleCircle Circl_two(Circl_one);
    cout<<Circl_two.GetRadius();
    return 0;
}
По идее должно скопироваться значение itsRad объекта Circl_one. Я правильно понял?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
17.08.2011, 14:09     Конструктор копировщик #2
ramarren14, getRadius const должна быть
silentnuke
Android Programmer
137 / 138 / 5
Регистрация: 08.12.2010
Сообщений: 421
17.08.2011, 14:11     Конструктор копировщик #3
ибо должно быть так
C++
1
int GetRadius () const {return *itsRad;}
константные объекты, не могу работать с не константными функциями.
ramarren14
2 / 2 / 0
Регистрация: 14.07.2011
Сообщений: 49
17.08.2011, 14:18  [ТС]     Конструктор копировщик #4
Cпасибо. Буду внимательнее.
Сыроежка
Заблокирован
17.08.2011, 15:17     Конструктор копировщик #5
Цитата Сообщение от ramarren14 Посмотреть сообщение
Самостоятельно изучаю С++ по Либерти(освой за 21 день)
Требуется создать класс и конструктор копировщик. Компилятор Visual C++ 2010.
Выдает ошибку:
1>c:\users\selver\documents\visual studio 2010\projects\bufer\bufer\hgfh.cpp(42): error C2662: 'SimpleCircle::GetRadius' : cannot convert 'this' pointer from 'const SimpleCircle' to 'SimpleCircle &'

Хотя в книге написано что должно работать.
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
#include<iostream>
using namespace std;
 
class SimpleCircle{
public:
    SimpleCircle();
    ~SimpleCircle();
    SimpleCircle (const SimpleCircle &);
    int GetRadius (){return *itsRad;}
    void SetRadius(int x){*itsRad=x;}
    
private:
    int *itsRad;
};
 
SimpleCircle::SimpleCircle(){
    itsRad=new int;
    *itsRad=10;
}
 
 
 
 
SimpleCircle::~SimpleCircle(){
    delete itsRad;
    itsRad=0;
}
 
SimpleCircle::SimpleCircle (const SimpleCircle & rhs){
    itsRad=new int;
    *itsRad=rhs.GetRadius();
}
 
 
int main(){
    SimpleCircle Circl_one;
    SimpleCircle Circl_two(Circl_one);
    cout<<Circl_two.GetRadius();
    return 0;
}
По идее должно скопироваться значение itsRad объекта Circl_one. Я правильно понял?
Помимо синтаксической ошибки, что вы для константной ссылки вызываете неконстатный метод GetRadius, в вашем коде имеется серьезная ошибка утечки памяти.

Если один объект вашего класса присваивается другому объекту вашего класса, то происходит простое почленное копирование данных. А это значит, предыдущее значение указателя на int у вас просто теряется.
Вам нужно самому переопределить оператор присваивания, который будет аналогичен оператору копирования.

Можно написать обобщенный оператор присваивания.

C++
1
2
3
4
5
6
7
SimpleCircle & SimpleCircle::operator =  (const SimpleCircle & rhs )
{
   this->~SimpleCircle();
   new ( this ) SimpleCircle( rhs );
 
   return ( *this );
}
rvma
0 / 0 / 0
Регистрация: 04.03.2015
Сообщений: 5
04.03.2015, 14:42     Конструктор копировщик #6
Цитата Сообщение от Сыроежка Посмотреть сообщение
в вашем коде имеется серьезная ошибка утечки памяти.
Если один объект вашего класса присваивается другому объекту вашего класса, то происходит простое почленное копирование данных. А это значит, предыдущее значение указателя на int у вас просто теряется.
Добрый день. Тоже учу С++ по Либерти. Возник вопрос по ответу на вопрос выше Мне не ясно почему происходит утечка памяти. Ведь в деструкторе прописана очистка. Если создать копию объекта, то для копии будет происходить вызов деструктора. Даже...пусть будет копия через оператор =, если создается даже временная копия объекта то будет и копия указателей на память, а раз есть указатель, значит деструктор ее очистит, и у нас есть к ней доступ. Не понимаю логику. Гибкость С++ иногда сводит с ума)
Ilot
Модератор
Эксперт С++
1765 / 1140 / 221
Регистрация: 16.05.2013
Сообщений: 3,017
Записей в блоге: 5
Завершенные тесты: 1
04.03.2015, 14:57     Конструктор копировщик #7
Ошибка утечки памяти связана с отсутствием опреатора присваения. В посте выше это указано.
rvma
0 / 0 / 0
Регистрация: 04.03.2015
Сообщений: 5
04.03.2015, 15:26     Конструктор копировщик #8
В посте выше: "Если один объект вашего класса присваивается другому объекту вашего класса, то происходит простое почленное копирование данных. А это значит, предыдущее значение указателя на int у вас просто теряется." Но предыдущее значение указателя находится в предыдущем объекте, для которого есть деструктор. Исходя из этой логики, если происходит простое почленное копирование, значит вызывается копировщик по умолчанию, значит оба объекта будут ссылаться на одну ячейку, а по скольку копировщик берет объект по ссылке, то временной копии у нас иметься не будет. И если один из объектов завершит свою работу, то тогда появятся проблемы. Я правильно понял? Но Либерти пишет, что если копировщик определен пользователем, то копировщик по умолчанию не вызывается. И не ясно где отсутствует оператор присвоения? В каком месте?

Добавлено через 14 минут
Хочу уточнить свой вопрос. Не ясно по какой причине происходит утечка, исходя из моей логики выше) Как исправляется эта проблема, как я понял перегрузкой оператора присваивания - уже отдельный вопрос.
GREGOR_812
 Аватар для GREGOR_812
25 / 25 / 3
Регистрация: 23.04.2014
Сообщений: 123
04.03.2015, 15:43     Конструктор копировщик #9
rvma, мысль правильная. Есть "правило трёх", которое гласит, что если переопределён конструктор копирования, оператор присваивания или деструктор, то нужно переопределять и остальные два.
Цитата Сообщение от Ilot Посмотреть сообщение
Ошибка утечки памяти связана с отсутствием опреатора присваения.
Не совсем точно сформулирована фраза. Здесь имелось ввиду как раз то, что оператор присваивания не определён. Поэтому при вызове конструкции типа
C++
1
2
3
Obj a(/* some params */);
Obj b(/* some params */);
b = a;
вызовется оператор присваивания по умолчанию, который тупо скопирует все поля, в том числе и указатели, объекта а. Таким образом, мы получим не только двойное освобождение памяти при уничтожении объектов, но и утечку, т.к. указатель объекта b до присваивания указывал на какую-то выделенную память, а в процессе копирования он был утерян.
rvma
0 / 0 / 0
Регистрация: 04.03.2015
Сообщений: 5
04.03.2015, 15:48     Конструктор копировщик #10
Теперь врубился, благодарствую)))))))))))))
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.03.2015, 15:55     Конструктор копировщик
Еще ссылки по теме:

C++ Конструктор-копировщик
Конструктор копировщик объектов, содержащих массивы C++
C++ Стандартный конструктор копировщик и оператор = не справляются со своей задачей

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

Или воспользуйтесь поиском по форуму:
GREGOR_812
 Аватар для GREGOR_812
25 / 25 / 3
Регистрация: 23.04.2014
Сообщений: 123
04.03.2015, 15:55     Конструктор копировщик #11
rvma, помимо этого, нужно учесть ситуацию, когда присваивание происходит самому себе. Оператор присваивания возвращает ссылку на объект.
Yandex
Объявления
04.03.2015, 15:55     Конструктор копировщик
Ответ Создать тему
Опции темы

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