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

C++

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 41, средняя оценка - 4.88
OVERPOWER8
19 / 19 / 1
Регистрация: 29.11.2009
Сообщений: 224
#1

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

20.01.2010, 14:16. Просмотров 4987. Ответов 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;
}
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Genius Ignat
1235 / 773 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
20.01.2010, 16:51     Как передалеть operator= класса? #41
zim22:
Ты мне скажи где ты это достал.
zim22
depict1
276 / 141 / 2
Регистрация: 11.07.2009
Сообщений: 606
20.01.2010, 16:55     Как передалеть operator= класса? #42
Genius Ignat, мне не интересно с тобой общаться. и я тебе ничего не должен.
Genius Ignat
1235 / 773 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
20.01.2010, 16:56     Как передалеть operator= класса? #43
Ты прав.
Но я тоже.
Сейчас откомпилировал две программы.
Одну на VC++ 6.0: При запуске опять ошибка
Другую на Visual Studio 2008: При запуске всё норм.
insideone
Модератор
Автор FAQ
3636 / 914 / 49
Регистрация: 10.01.2010
Сообщений: 2,464
20.01.2010, 16:57     Как передалеть operator= класса? #44
Жесть все серёзные.
2 Genius Ignat Узнать можно по нажатию F11 в VS 2008 по крайне мере) но только в режиме дебага) это будет - dbgdel.cpp
Genius Ignat
1235 / 773 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
20.01.2010, 16:58     Как передалеть operator= класса? #45
Буду знать: что на программы на старом компиляторе ни чего хорошего.

Добавлено через 1 минуту
insideone:
узнавать пока я ни чего не собирался.
CyBOSSeR
Эксперт C++
2299 / 1669 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
20.01.2010, 17:05     Как передалеть operator= класса? #46
OVERPOWER8, я тебе уже говорил про опастность использования указателей для храниения таких примитивных данных как возраст. Ты не хотел слушать и вот результат - в простейшем классе серьезная и очень неприятная ошибка. А если класс в 10 раз больше и классов не один десяток?
Никакое удобство не оправдывает опастности связанные с использованием указателей, там где они не нужны - избавься от такой практики.

Как уже было написано - не хватало конструктора копирования.
Поэтому у тебя указатели itsAge и itsWeight после выполнения строки
C++
1
CAT whiskers = Frisky;
указывают на одни и те же области памяти.


Вот рабочий вариант твоего кода (по крайне мере, codepad.org выдает ожидаемый результат).
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
#include <iostream>
 
using namespace std;
 
class CAT
{
        public:
                CAT();
                CAT(const CAT& rhs);
                ~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(const CAT& rhs)
{
       itsAge = new int;
       itsWeight = new int;
 
       *itsAge    = rhs.GetAge();
       *itsWeight = rhs.GetWeight();
}
 
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;
}
И еще:
C++
1
2
3
4
5
6
7
8
CAT::~CAT()
{
  delete itsAge;
  itsAge = 0;
 
  delete itsWeight;
  itsWeight = 0;
}
Вместо 0 используй NULL. 0 - непереносимый вариант нулевого указателя. Подробнее здесь.
OVERPOWER8
19 / 19 / 1
Регистрация: 29.11.2009
Сообщений: 224
20.01.2010, 18:44  [ТС]     Как передалеть operator= класса? #47
>> CyBOSSeR
А ты почитай Страуструпа про NULL - он рекомендует обратное - вместо NULL использовать 0!


>> Genius Ignat >> zim22
Вы пользуетесь компиляторами с поблажками, и толком не знаете, как работают указатели, т. к. ваши компиляторы на некоторые оплошности закрывают глаза...
zim22
depict1
276 / 141 / 2
Регистрация: 11.07.2009
Сообщений: 606
20.01.2010, 18:51     Как передалеть operator= класса? #48
Цитата Сообщение от OVERPOWER8 Посмотреть сообщение
и толком не знаете, как работают указатели,
ну и как они работают, просвети?
OVERPOWER8
19 / 19 / 1
Регистрация: 29.11.2009
Сообщений: 224
20.01.2010, 19:14  [ТС]     Как передалеть operator= класса? #49
>> zim22
почитай умную книжку:
http://www.rsdn.ru/res/book/cpp/cpp_bible.xml
zim22
depict1
276 / 141 / 2
Регистрация: 11.07.2009
Сообщений: 606
20.01.2010, 19:16     Как передалеть operator= класса? #50
Цитата Сообщение от OVERPOWER8 Посмотреть сообщение
почитай умную книжку:
у меня уже реакция вырабатывается - если не отвечают, а рекомендуют почитать умную книжку, то это значит одно из двух: или я не в теме, или советчик. в данном случае - советчик
CyBOSSeR
Эксперт C++
2299 / 1669 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
20.01.2010, 19:27     Как передалеть operator= класса? #51
Цитата Сообщение от OVERPOWER8 Посмотреть сообщение
>> CyBOSSeR
А ты почитай Страуструпа про NULL - он рекомендует обратное - вместо NULL использовать 0!
Ни разу про такое не слышал. В какой именно книге? В "Язык прграммирования C++" даже упоминания про NULL нет. В посте на который я тебе указывал, Evg приводил примеры непереносимого кода, как раз таки из-за использования 0 вместо NULL.

Может быть ты все таки расскажешь, почему для хранения таких данных как возраст ты используешь указатели, при условии, что:
1. Это не безопасно и ты на этом примере должен был убедится в этом.
2. На это уходит больше памяти (сами данные + указатель на них).
Ты говорил, что так удобнее. В чем выражается это удобство, если приходится писать уйму кода только для того, чтобы обеспечить безопасность при работе с указателями?

Цитата Сообщение от OVERPOWER8 Посмотреть сообщение
Вы пользуетесь компиляторами с поблажками, и толком не знаете, как работают указатели, т. к. ваши компиляторы на некоторые оплошности закрывают глаза...
Хотелось бы услышать как все таки "работают" указатели?

Добавлено через 1 минуту
Цитата Сообщение от OVERPOWER8 Посмотреть сообщение
>> zim22
почитай умную книжку:
http://www.rsdn.ru/res/book/cpp/cpp_bible.xml
А если своими словами?
Genius Ignat
1235 / 773 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
20.01.2010, 19:44     Как передалеть operator= класса? #52
Да действительно зачем здесь указатели, какая от них выгода.
zim22
depict1
276 / 141 / 2
Регистрация: 11.07.2009
Сообщений: 606
20.01.2010, 20:22     Как передалеть operator= класса? #53
Цитата Сообщение от CyBOSSeR Посмотреть сообщение
0 вместо NULL.
скоро мучения кончатся. в С++0x будет ключевое слово nullptr
CyBOSSeR
Эксперт C++
2299 / 1669 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
20.01.2010, 20:31     Как передалеть operator= класса? #54
Цитата Сообщение от zim22 Посмотреть сообщение
скоро мучения кончатся. в С++0x будет ключевое слово nullptr
Скоро-то скоро, но сколько времени еще пройдет до того момента как компиляторы начнут его поддерживать.
zim22
depict1
276 / 141 / 2
Регистрация: 11.07.2009
Сообщений: 606
20.01.2010, 20:35     Как передалеть operator= класса? #55
Цитата Сообщение от CyBOSSeR Посмотреть сообщение
но сколько времени еще пройдет до того момента как компиляторы начнут его поддерживать.
msvc 2010 уже
insideone
Модератор
Автор FAQ
3636 / 914 / 49
Регистрация: 10.01.2010
Сообщений: 2,464
20.01.2010, 20:41     Как передалеть operator= класса? #56
Bjarne Stroustrup. The C++ programming language. Special edition. 3rd. ed.
5.1.1 Zero [ptr.zero]
Zero (0) is an int. Because of standard conversions (§C.6.2.3), 0 can be used as a constant of any
integral (§4.1.1), floating-point, pointer, or pointer-to-member type. The type of zero will be deter-
mined by context. Zero will typically (but not necessarily) be represented by the bit pattern all-
zeros of the appropriate size.
No object is allocated with the address 0. Consequently, 0 acts as a pointer literal, indicating
that a pointer doesn’t refer to an object.
In C, it has been popular to define a macro NULL to represent the zero pointer. Because of
C++’s tighter type checking, the use of plain 0, rather than any suggested NULL macro, leads to
fewer problems. If you feel you must define NULL, use
const int NULL = 0;
The const qualifier (§5.4) prevents accidental redefinition of NULL and ensures that NULL can be
used where a constant is required.
вот и все что он пишет про NULL...
CyBOSSeR
Эксперт C++
2299 / 1669 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
20.01.2010, 20:42     Как передалеть operator= класса? #57
Цитата Сообщение от zim22 Посмотреть сообщение
msvc 2010 уже
Но как-то не хочется перелезать с MSVS 2005.
zim22
depict1
276 / 141 / 2
Регистрация: 11.07.2009
Сообщений: 606
20.01.2010, 20:45     Как передалеть operator= класса? #58
Цитата Сообщение от CyBOSSeR Посмотреть сообщение
Но как-то не хочется перелезать с MSVS 2005.
вспоминаются люди, которые до сих пор сидят на Borland C++ 3.0
CyBOSSeR
Эксперт C++
2299 / 1669 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
21.01.2010, 00:43     Как передалеть operator= класса? #59
Цитата Сообщение от insideone Посмотреть сообщение
5.1.1 Zero [ptr.zero]
Zero (0) is an int. Because of standard conversions (§C.6.2.3), 0 can be used as a constant of any
integral (§4.1.1), floating-point, pointer, or pointer-to-member type. The type of zero will be deter-
mined by context. Zero will typically (but not necessarily) be represented by the bit pattern all-
zeros of the appropriate size.
No object is allocated with the address 0. Consequently, 0 acts as a pointer literal, indicating
that a pointer doesn’t refer to an object.
In C, it has been popular to define a macro NULL to represent the zero pointer. Because of
C++’s tighter type checking, the use of plain 0, rather than any suggested NULL macro, leads to
fewer problems. If you feel you must define NULL, use
const int NULL = 0;
The const qualifier (§5.4) prevents accidental redefinition of NULL and ensures that NULL can be
used where a constant is required.
OVERPOWER8, прочитай это ВНИМАТЕЛЬНО прежде чем говорить что Страуструп рекомендует 0 вместо NULL.

Добавлено через 3 часа 55 минут
OVERPOWER8, так ты ответишь на озвученные вопросы?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.01.2010, 01:25     Как передалеть operator= класса?
Еще ссылки по теме:

Перегрузка operator* у класса Complex C++
C++ Перегрузка operator< для двух экземпляров класса отрезок
Перегрузка operator>> для производного класса C++
C++ Перегрузить operator<<() для шаблонного класса (перегрузка оператора вывода)
C++ Реализовать перегрузку operator+() для пользователского класса

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

Или воспользуйтесь поиском по форуму:
insideone
Модератор
Автор FAQ
3636 / 914 / 49
Регистрация: 10.01.2010
Сообщений: 2,464
21.01.2010, 01:25     Как передалеть operator= класса? #60
В 36 посту я даю ссылку на Википедию Как передалеть operator= класса?
Там внизу написано:
В отличие от классического Си в C++ значение пустого указателя предопределено стандартом языка и всегда равно 0 (целочисленному нулю, приведённому к типу «указатель»). Поэтому в программах на C++ не только возможно, но и рекомендуется использовать значение 0 вместо NULL[1], (в отличие от макроса NULL, числовое значение не может быть случайно переопределено), однако некоторые программисты считают, что это ухудшает читаемость исходного кода.
[1] - это ссылка на книгу Страуструпа. Возможно это было воспринято OVERPOWER8, однако оказывается википедия не точна в выражениях, т.к. Страуструп всего лишь советовал, опасаясь того что NULL будет не 0. Странно как то. Вот кстати в русской редакции как написано. Мало ли:
5.1.1. Ноль
Ноль (0) имеет тип int. Благодаря стандартным преобразованиям, 0 можно использовать в качестве константы любого интегрального типа, типа с плавающей точкой, указателя или указателя на член класса. Тип нуля определяется по контексту. Ноль, как правило (но не всегда), будет физически представлен в виде последовательности нулевых битов соответствующей длинны.
Гарантируется, что нет объектов с нулевым адресом. Следовательно, указатель, равный нулю, можно интерпретировать как указатель, который ни на что не ссылается.
В языке C было очень популярно определять макрос NULL для представления такого нулевого указателя. Так как в C++ типы проверяются более жестко, использование банального нуля вместо NULL приведет к меньшим проблемам. Если вы чувствуете, что просто обязаны определить NULL, воспользуйтесь
const int NULL = 0,
Модицикатор const предотвращает ненамеренное замещение NULL и гарантирует, что NULL можно использовать везде где требуется константа.
Раз Страуструп так боится за NULL почему бы у себя не завести какой нибудь XNULL и пользоваться им на здоровье?)) а заменить его на обычный NULL не проблема (автоматическая замена рулит). Впрочем бессмысленно это как то все, глупости)
Yandex
Объявления
21.01.2010, 01:25     Как передалеть operator= класса?
Ответ Создать тему
Опции темы

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