Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.53/34: Рейтинг темы: голосов - 34, средняя оценка - 4.53
19 / 19 / 2
Регистрация: 29.11.2009
Сообщений: 224
1

Как передалеть operator= класса?

20.01.2010, 14:16. Показов 6292. Ответов 78
Метки нет (Все метки)

Вот готовая программа, но там одна проблема - после использования оператора=, при изменении значений в одном объекте класса, они изменяются и в другом. Другими словами, как сделать так, чтобы вывод программы был:

Frisky's age: 5
whisker's age: 6

а не

Frisky's age: 5
whisker's age: 0

Вот код программы:

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 <iostream>
using namespace std;
 
class CAT
{
    public:
        CAT();
        ~CAT();
        
        int GetAge() const { return *itsAge; }
        int GetWeight() const { return *itsWeight; }
        void SetAge(int age) { *itsAge = age; }
        CAT& operator=(const CAT&);
    
    private:
        int* itsAge;
        int* itsWeight;
};
 
CAT::~CAT()
{
    delete itsAge; itsAge=0;
    delete itsWeight; itsWeight=0;
}
 
CAT::CAT()
{
    itsAge = new int;
    itsWeight = new int;
    *itsAge = 5;
    *itsWeight=9;
}
 
CAT& CAT::operator=(const CAT& rhs)
{
    if(this == &rhs)
        return *this;
    
    *itsAge=rhs.GetAge();
    *itsWeight=rhs.GetWeight();
    return *this;
}
 
int main()
{
    CAT Frisky;
    cout << "Frisky's age: " << Frisky.GetAge() << endl;
    Frisky.SetAge(6);
    
    CAT whiskers = Frisky;
    Frisky.SetAge(0);
    cout << "whisker's age: " << whiskers.GetAge() << endl;
    
    return 0;
}
1

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
20.01.2010, 14:16
Ответы с готовыми решениями:

operator+ как член класса
Могу ли я сделать operator+ как член класса таким образом? myClass&amp; myClass::operator+(const...

Как перенести operator из базового класса в производный?
Добрый день! Подскажите, пожалуйста, на простых примерах, как нужно работать с оператором...

Класс: Почему этот operator+ не хочет работать как функция внутри класса?
#include &lt;iostream&gt; #include &lt;conio.h&gt; using namespace std; class complex{ private: int...

operator[][] для класса
Добрый день, создал класс где храниться массив, и хотелось бы иметь напрямю доступ через по типу ...

78
Автор FAQ
3684 / 961 / 114
Регистрация: 10.01.2010
Сообщений: 2,550
20.01.2010, 15:44 21
А разве выполняется констуктор по умолчанию (в смысле генерируемый компилятором стандатный и тупой)? Помоему выполняется конструктор копирования который я сам написал О_о мне стало страшно запутаться, ведь я только подумал что понял это! Пожалуйста проверьте код построчно и посмотрите что выполняется чтобы убедиться точно... По мне код выполняется правильно как и требовалось без всяких везений...
0
19 / 19 / 2
Регистрация: 29.11.2009
Сообщений: 224
20.01.2010, 16:02  [ТС] 22
Вроде бы все работает, но память немного утекает:
C++
1
2
3
4
5
6
CAT::CAT(CAT& From)
{
          itsAge = new int;
        *itsAge = *From.itsAge;
 
}
0
Maniac
Эксперт С++
1455 / 956 / 159
Регистрация: 02.01.2009
Сообщений: 2,816
Записей в блоге: 1
20.01.2010, 16:05 23
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
#include <iostream>
using namespace std;
 
class Cat
{
public:
    Cat();
    Cat(int, int);
    Cat(const Cat&);
 
    ~Cat();
 
    int GetAge()    const   { return *itsAge; }
    int GetWeight() const   { return *itsWeight; }
    void SetAge(int age)    { *itsAge = age; }
 
    Cat& operator = (const Cat&);
 
private:
    int* itsAge;
    int* itsWeight;
};
 
Cat::~Cat()
{
    delete itsAge;      itsAge      = 0;
    delete itsWeight;   itsWeight   = 0;
}
 
Cat::Cat()
    : itsAge(0), itsWeight(0)
{
    itsAge      = new int;
    itsWeight   = new int;
 
    *itsAge     = 0;
    *itsWeight  = 0;
}
 
Cat::Cat(int a, int b)
    : itsAge(0), itsWeight(0)
{
    itsAge      = new int;
    itsWeight   = new int;
 
    *itsAge     = a;
    *itsWeight  = b;
}
Cat::Cat(const Cat& rhs)
    : itsAge(0), itsWeight(0)
{
    *this = rhs;
}
 
Cat& Cat::operator = (const Cat& rhs)
{
    if(this == &rhs)
        return *this;
 
    delete itsAge;
    delete itsWeight;
 
    itsAge      = new int;
    itsWeight   = new int;
 
    *itsAge     = rhs.GetAge();
    *itsWeight  = rhs.GetWeight();
 
    return *this;
}
 
int main()
{
    Cat Frisky;
    cout << "Frisky's age: " << Frisky.GetAge() << endl;
    Frisky.SetAge(6);
 
    Cat whiskers = Frisky;
    Frisky.SetAge(0);
    cout << "whisker's age: " << whiskers.GetAge() << endl;
 
    {
        Cat x(10,15);
 
        cout << "x age: " << x.GetAge() << endl;
 
        Frisky = x;
    }
 
 
    cout << "Frisky's " << Frisky.GetWeight() << endl;
 
    return 0;
}
2
1258 / 796 / 108
Регистрация: 16.09.2009
Сообщений: 2,010
20.01.2010, 16:12 24
ISergey
C++
1
2
3
4
5
Cat::Cat(const Cat& rhs)
        : itsAge(0), itsWeight(0)
{
        *this = rhs;
}
Хитёр.

Добавлено через 1 минуту
В некоторых случаях сам таким способом пользуюсь.

Добавлено через 1 минуту
Единственно^ в сзязи с этим надо переделать деструктор
C++
1
2
3
4
5
6
7
Cat::~Cat()
{
        if((itsAge!=0)&&(itsWeight!=0)){
        delete itsAge;          itsAge          = 0;
        delete itsWeight;       itsWeight       = 0;
}
}
0
Maniac
Эксперт С++
1455 / 956 / 159
Регистрация: 02.01.2009
Сообщений: 2,816
Записей в блоге: 1
20.01.2010, 16:13 25
Единственно^ в сзязи с этим надо переделать деструктор
Зачем?
0
depict1
281 / 146 / 4
Регистрация: 11.07.2009
Сообщений: 606
20.01.2010, 16:13 26
Цитата Сообщение от Genius Ignat Посмотреть сообщение
Хитёр.
может быть Ленив?

конструктор копирования реализованный на базе оператора присвоения делает ненужные ему вещи: удаляет только что созданные переменные и проводит проверку на равенство, которая никогда не будет true
0
1258 / 796 / 108
Регистрация: 16.09.2009
Сообщений: 2,010
20.01.2010, 16:14 27
Вот пример из простого:
void main(){

int * a =0;
delete a; //что будет как думаешь.

}
0
Автор FAQ
3684 / 961 / 114
Регистрация: 10.01.2010
Сообщений: 2,550
20.01.2010, 16:15 28
2 Genius Ignat А зачем? Ведь везде делается new int что исключает появление 0... или нет? (кроме случая когда память кончилась :-D )
0
1258 / 796 / 108
Регистрация: 16.09.2009
Сообщений: 2,010
20.01.2010, 16:20 29
[CPP]Cat::Cat(const Cat& rhs)
: itsAge(0), itsWeight(0)
{
*this = rhs;
}[/CPP
no comment]
Ты внимательно весь пост почитай проблема не в операции =

Добавлено через 1 минуту

Вот ещё кое-что заметил только в операции =
C++
1
2
3
4
5
6
        
 if(this == &rhs)
                return *this;
 
        delete itsAge;        //опасно  itsAge ==NULL;
        delete itsWeight;    //опасно  itsWeight ==NULL;
Добавлено через 1 минуту
переделывается аналогично деструктору
0
Maniac
Эксперт С++
1455 / 956 / 159
Регистрация: 02.01.2009
Сообщений: 2,816
Записей в блоге: 1
20.01.2010, 16:24 30
Открой стандарт и прочти пункт 5.3.5
http://codepad.org/jthmcAuD
0
1258 / 796 / 108
Регистрация: 16.09.2009
Сообщений: 2,010
20.01.2010, 16:25 31
ISergey:
У тебя какой компилятор:
C++
1
2
3
4
5
6
void main(){
 
int * a =0;
delete a; //что будет как думаешь.
 
}
И что программа работает.
0
depict1
281 / 146 / 4
Регистрация: 11.07.2009
Сообщений: 606
20.01.2010, 16:29 32
Цитата Сообщение от Genius Ignat Посмотреть сообщение
У тебя какой компилятор
причём здесь компилятор? есть поведение, регламентированное стандартом.

если попытаться удалить нулевой указатель - то ничего не будет
0
1258 / 796 / 108
Регистрация: 16.09.2009
Сообщений: 2,010
20.01.2010, 16:30 33
Странно Windows выкидывает ошибку.
0
depict1
281 / 146 / 4
Регистрация: 11.07.2009
Сообщений: 606
20.01.2010, 16:32 34
Цитата Сообщение от Genius Ignat Посмотреть сообщение
Странно Windows выкидывает ошибку.
а чайник на кухне не кипит? ...
1
1258 / 796 / 108
Регистрация: 16.09.2009
Сообщений: 2,010
20.01.2010, 16:35 35
удалить нулевой указатель - то ничего не будет
Вообще то мы не указатель удаляем, мы освобождаем память через её адрес в указателе.

Добавлено через 52 секунды
Значит у меня такая умная ОС.

Добавлено через 2 минуты
А посути мы пытаемся обратиться по нулевому адресу, что бы его освободить.
Вот такую ошибку Windows и выдает.
0
Автор FAQ
3684 / 961 / 114
Регистрация: 10.01.2010
Сообщений: 2,550
20.01.2010, 16:36 36
Нулевые указатели придуманы как удобный способ «отметить» указатели, которые заведомо не указывают на корректный адрес в памяти.
Хорошим стилем программирования является присваивание указателю после освобождения памяти, на которую он ссылался, нулевого указателя, так как автоматически этого не происходит (зачастую, после освобождения памяти значение адреса, на который указывает указатель, остается тем же, но память уже может быть недоступна и выделена под другой объект). Кроме этого, применение обнуления указателей актуально для безопасности освобождения памяти: операция delete безопасна для нулевого указателя.
by http://ru.wikipedia.org/wiki/NULL_(Си)

Не по теме:

Читал недавно у разработчиков игр на консоли с этим проблемы, т.к. там нулевой адресс не обладает такими св-вами. А нам вот все удобства! =)

0
1258 / 796 / 108
Регистрация: 16.09.2009
Сообщений: 2,010
20.01.2010, 16:42 37
Освобождение адреса: 0x00000000, ни к чему хорошему не приводит.

Добавлено через 30 секунд
insideone:
А ты думаешь я этого не знаю.

Добавлено через 52 секунды
Наверное не все ОС адекватно реагируют на такое событие.

Добавлено через 1 минуту
Не зря в библиотеки ATL,
в интеллектуальных указателях есть макросы assert выбрасывающие сообщение об ошибке:
которые осведомляю о подобных ситуации: обращению к NULL адресу.

Добавлено через 2 минуты
insideone
Меня твои цитаты не удивляют.
0
depict1
281 / 146 / 4
Регистрация: 11.07.2009
Сообщений: 606
20.01.2010, 16:43 38
Цитата Сообщение от Genius Ignat Посмотреть сообщение
Освобождение адреса: 0x00000000, ни к чему хорошему не приводит.
а с чего ты взял что он освобождается?
посмотри реализацию operator delete
1
1258 / 796 / 108
Регистрация: 16.09.2009
Сообщений: 2,010
20.01.2010, 16:46 39
zim22:
А ты посмотри atlbase.h

Добавлено через 43 секунды
Вдруг что то изменилось, сейчас по смотрю у себя в Visual Studio 2008

Добавлено через 1 минуту
посмотри реализацию operator delete
где посмотреть?
0
depict1
281 / 146 / 4
Регистрация: 11.07.2009
Сообщений: 606
20.01.2010, 16:48 40
Цитата Сообщение от Genius Ignat Посмотреть сообщение
где посмотреть?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
void operator delete(
        void *pUserData
        )
{
        _CrtMemBlockHeader * pHead;
 
        RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));
 
        if (pUserData == NULL)   // !!!!!! ФОКУС-ПОКУС
            return;
 
        _mlock(_HEAP_LOCK);  /* block other threads */
         ...
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
20.01.2010, 16:48

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Operator< для класса
Всем добра, что-то я туплю подскажите как определить operator&lt; для класса, в классе два значение...

Перегрузка operator* у класса Complex
Complex* Complex::operator*(const Complex&amp; other) const { Complex* product = this; ...

Не работает operator<< шаблонного класса Vector
Компилятор выдает ошибку error LNK2019: unresolved external symbol &quot;class...

Перегрузка operator>> для производного класса
Базовый класс: Taxi_Car.h: #pragma once #include&lt;string&gt; using namespace std; class...


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

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

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