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

C++

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

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

20.01.2010, 14:16. Просмотров 5164. Ответов 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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.01.2010, 14:16
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Как передалеть operator= класса? (C++):

operator [что попало] - C++
Кто пользуется перегрузками типа class TPoint {public: double x,y,z;} class B {public: operator operator (TPoint);}, class B {public:...

Перегрузка operator+ в собственном класе MyString - C++
Хочу сделать перегрузить оператор +, что бы можно было делать: /* ... */ MyString a = MyString(&quot;name&quot;); MyString b = MyString(&quot;...

Как исправить ошибку - Could not find a match for 'operator AnsiString::=(TDateTime)' - C++ Builder
Организовать хранение данных в файле в следущую структуру, фио, дата, время 1) Написать процедуру считывания этого файла 2) Сколько раз...

Как правильно создать массив объектов текущего класса в методе данного класса? - C++ Builder
Привет! Ставится задача создания метода, который формирует массив объектов. Правильно ли делать этот метод внутри класса, экземпляром...

operator= - C++ Builder
class mnogo4len { protected: int *N; float *koef; public: mnogo4len(); //конструктор ...

Трудности с перегрузкой operator<< - Visual C++
такая пробла.. когда перегружаю operator&lt;&lt; возникает какоя ошибка Ошибка 1 error C2662: TBitField::GetBit: невозможно преобразовать...

78
CyBOSSeR
Эксперт С++
2305 / 1675 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
20.01.2010, 17:05 #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 - непереносимый вариант нулевого указателя. Подробнее здесь.
0
OVERPOWER8
19 / 19 / 1
Регистрация: 29.11.2009
Сообщений: 224
20.01.2010, 18:44  [ТС] #47
>> CyBOSSeR
А ты почитай Страуструпа про NULL - он рекомендует обратное - вместо NULL использовать 0!


>> Genius Ignat >> zim22
Вы пользуетесь компиляторами с поблажками, и толком не знаете, как работают указатели, т. к. ваши компиляторы на некоторые оплошности закрывают глаза...
0
zim22
depict1
276 / 141 / 2
Регистрация: 11.07.2009
Сообщений: 606
20.01.2010, 18:51 #48
Цитата Сообщение от OVERPOWER8 Посмотреть сообщение
и толком не знаете, как работают указатели,
ну и как они работают, просвети?
0
OVERPOWER8
19 / 19 / 1
Регистрация: 29.11.2009
Сообщений: 224
20.01.2010, 19:14  [ТС] #49
>> zim22
почитай умную книжку:
http://www.rsdn.ru/res/book/cpp/cpp_bible.xml
0
zim22
depict1
276 / 141 / 2
Регистрация: 11.07.2009
Сообщений: 606
20.01.2010, 19:16 #50
Цитата Сообщение от OVERPOWER8 Посмотреть сообщение
почитай умную книжку:
у меня уже реакция вырабатывается - если не отвечают, а рекомендуют почитать умную книжку, то это значит одно из двух: или я не в теме, или советчик. в данном случае - советчик
0
CyBOSSeR
Эксперт С++
2305 / 1675 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
20.01.2010, 19:27 #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
А если своими словами?
0
Genius Ignat
1237 / 775 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
20.01.2010, 19:44 #52
Да действительно зачем здесь указатели, какая от них выгода.
0
zim22
depict1
276 / 141 / 2
Регистрация: 11.07.2009
Сообщений: 606
20.01.2010, 20:22 #53
Цитата Сообщение от CyBOSSeR Посмотреть сообщение
0 вместо NULL.
скоро мучения кончатся. в С++0x будет ключевое слово nullptr
0
CyBOSSeR
Эксперт С++
2305 / 1675 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
20.01.2010, 20:31 #54
Цитата Сообщение от zim22 Посмотреть сообщение
скоро мучения кончатся. в С++0x будет ключевое слово nullptr
Скоро-то скоро, но сколько времени еще пройдет до того момента как компиляторы начнут его поддерживать.
0
zim22
depict1
276 / 141 / 2
Регистрация: 11.07.2009
Сообщений: 606
20.01.2010, 20:35 #55
Цитата Сообщение от CyBOSSeR Посмотреть сообщение
но сколько времени еще пройдет до того момента как компиляторы начнут его поддерживать.
msvc 2010 уже
1
insideone
Модератор
Автор FAQ
3643 / 922 / 51
Регистрация: 10.01.2010
Сообщений: 2,480
20.01.2010, 20:41 #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...
0
CyBOSSeR
Эксперт С++
2305 / 1675 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
20.01.2010, 20:42 #57
Цитата Сообщение от zim22 Посмотреть сообщение
msvc 2010 уже
Но как-то не хочется перелезать с MSVS 2005.
0
zim22
depict1
276 / 141 / 2
Регистрация: 11.07.2009
Сообщений: 606
20.01.2010, 20:45 #58
Цитата Сообщение от CyBOSSeR Посмотреть сообщение
Но как-то не хочется перелезать с MSVS 2005.
вспоминаются люди, которые до сих пор сидят на Borland C++ 3.0
0
CyBOSSeR
Эксперт С++
2305 / 1675 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
21.01.2010, 00:43 #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, так ты ответишь на озвученные вопросы?
0
insideone
Модератор
Автор FAQ
3643 / 922 / 51
Регистрация: 10.01.2010
Сообщений: 2,480
21.01.2010, 01:25 #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 не проблема (автоматическая замена рулит). Впрочем бессмысленно это как то все, глупости)
0
21.01.2010, 01:25
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.01.2010, 01:25
Привет! Вот еще темы с ответами:

Error C2593: 'operator +=' is ambiguous - Visual C++
вообщем тема такая учусь програмить все когда то этим занимались, вот запоролся на вводе текста с клавиатуры: void...

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

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

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


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

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

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