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

Оператор присваивания. - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 24, средняя оценка - 4.92
pormonik
0 / 0 / 0
Регистрация: 26.09.2011
Сообщений: 40
10.01.2012, 21:55     Оператор присваивания. #1
Всем привет!В универе щас работаем с классами и перегрузками.В частности перегрузкой оператора присваивания и индексации.И я в упор не понимаю зачем это нужно.Например:
1)Оператор присваивания:
C++
1
2
3
4
5
6
class String {
String& operator = (String& s);        // перегрузка оператора присваивания
}
 
cout<<"\nОператор присваивания c=a\t";    
    String c=a;                                       // Само присваивание
Я не понимаю,зачем мы перегружаем оператор?Как он начинает ввести себя на программном уровне?Ведь обычный конструктор копирования передает побитово?Преподователь спрашивает,зачем мы используем ссылку во время перегрузки?Что будет если ее убрать?


2)Тоже самое про индексацию.Помогите пожалуйста всю голову сломал.Большое спасибо!
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.01.2012, 21:55     Оператор присваивания.
Посмотрите здесь:

C++ Оператор присваивания и деструктор
Оператор присваивания C++
C++ оператор присваивания
оператор присваивания C++
Оператор присваивания в c++ C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
NoMasters
Псевдослучайный
1737 / 1080 / 69
Регистрация: 13.09.2011
Сообщений: 3,094
10.01.2012, 22:21     Оператор присваивания. #2
Класс использует динамическую память для хранения строки символов, непосредственно в нём хранится только адрес и технические переменные. Если использовать конструктор копирования по умолчанию, получится, что адрес у обоих указывает на одну и ту же область памяти. Дальше, я думаю, понятно.
Обращение по индексу нужно, чтобы получить символ, находящийся в строке на определенном месте.
pormonik
0 / 0 / 0
Регистрация: 26.09.2011
Сообщений: 40
10.01.2012, 22:31  [ТС]     Оператор присваивания. #3
Тоесть в данном случае,в переменной (а) лежит адрес на первый элемент строки?И если использовать конструктор копирования,то у нас будет 2 переменных,в которых находится адрес,ссылающийся
на одинаковую область памяти?И если мы удалим переменную (а),то переменная (с) будет ссылаться на несуществующую область памяти?И тогда что происходит при перегрузке оператора?И зачем нужна ссылка?
Спасибо,это очень важно!!!
NoMasters
Псевдослучайный
1737 / 1080 / 69
Регистрация: 13.09.2011
Сообщений: 3,094
10.01.2012, 22:37     Оператор присваивания. #4
Не совсем, там структура данных объекта, в которой адрес том числе. В конструкторе копирования выделяется новый кусок памяти и туда копируется символьная строка из того объекта, который присваиваться. У каждого объекта получается по своей независимой копии.

Добавлено через 1 минуту
По ссылке строка передается, чтобы не нужно было лишний раз копировать всё содержание структуры данных объекта.
pormonik
0 / 0 / 0
Регистрация: 26.09.2011
Сообщений: 40
10.01.2012, 23:23  [ТС]     Оператор присваивания. #5
NoMasters, прости дружище,я не совсем понял что ты написал.Может быть на примере?

Добавлено через 35 минут
Может быть так правильно.Если делать стандартно, то массив будет один, а указателей на его начало два. Удаляя первый объект, мы удаляем указатель на начало массива и сам массив, после этого при попытке удалить второй объект мы получим ошибку, потому что там указатель ссылается на ничто. после перегрузки создается еще один массив, указатель в одном объекте ссылается на первый массив, во втором - на второй, и все ок работает
NoMasters
Псевдослучайный
1737 / 1080 / 69
Регистрация: 13.09.2011
Сообщений: 3,094
10.01.2012, 23:27     Оператор присваивания. #6
Можно открыть наконец книжку и прочитать о том, что такое объекты и как это работает. Предположим у нас есть какой-то такой класс строки:
C++
1
2
3
4
5
6
7
class String
{
public:
    size_t len;
    char *str;
    ...
};
Собственных данных у него только указатель на строку символов и её длина. При использовании стандартного конструктора копирования мы получим, что указатели в обоих объектах будут ссылаться на один и тот же кусок памяти. Чтобы этого избежать, напишем собственный конструктор копирования, который будет делать копии массива символов:
C++
1
2
3
4
5
6
7
8
9
String& String::operator = (const String& s)
{
    if (this != &s)
    {
        str = new char[s.len];
        memcpy(str, s.str, s.len);
    }
    return *this;
}
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
10.01.2012, 23:32     Оператор присваивания. #7
Поправте сигнатуру у оператора =. Строка в него должна передаваться по константной ссылке. Вы ведь не изменяете передаваемую строку в этом операторе? Иначе будут ошибки компиляции в некоторых случаях. например:
C++
1
2
3
const String str1;
String str2;
str2 = str1; // ошибка.
NoMasters
Псевдослучайный
1737 / 1080 / 69
Регистрация: 13.09.2011
Сообщений: 3,094
10.01.2012, 23:34     Оператор присваивания. #8
Точно, спасибо
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.01.2012, 23:43     Оператор присваивания.
Еще ссылки по теме:

Оператор присваивания C++
Оператор присваивания C++
Оператор присваивания по умолчанию C++

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

Или воспользуйтесь поиском по форуму:
Vergil111
31 / 31 / 6
Регистрация: 30.11.2010
Сообщений: 81
10.01.2012, 23:43     Оператор присваивания. #9
Начнем по порядку. Для начала разберем код, который вы привели в примере
Цитата Сообщение от pormonik Посмотреть сообщение
cout<<"\nОператор присваивания c=a\t"; * *
* * * * String c=a; * * * * * * * * * * * * * * * * * * * // Само присваивание
это НЕ присваивание.
В случаях, когда вы пишете
C++
1
2
String c=a; 
String c(a);
это вызывается конструктор копирования по умолчанию.
Далее рассматриваем начальную часть кода:
Цитата Сообщение от pormonik Посмотреть сообщение
class String {
String& operator = (String& s); * * * *// перегрузка оператора присваивания
}
опять же является неверной. Вы не можете осуществить возврат результата по ссылке при работе с локальными переменными данной функции.
Правильная запись будет выглядеть так:
C++
1
String operator = (String& s);
.
Теперь подробно про перегрузку оператора индексации.
Допустим у нас есть определение функции следующего вида:
C++
1
2
3
int& operator[](int n){
return arr[n]; //возвращаем некоторый элемент объекта класса, эмулирующего массив
}
Итак для чего это собственно надо и зачем возвращать элемент по ссылке:
C++
1
2
3
safearr sa1;//задал объект класса, эмулирующего массив
sa1[0]=10;//используем функцию слева от оператора равно(в этом случае возврат значения по ссылке нужен для инициализации элемента нашего массива).
int temp=sa1;//в этом случае мы используем функцию справа от знака равно и соответственно используем ее уже для получения значения в нашем массиве
и да, как верно заметил DU
Цитата Сообщение от DU Посмотреть сообщение
Строка в него должна передаваться по константной ссылке.
Yandex
Объявления
10.01.2012, 23:43     Оператор присваивания.
Ответ Создать тему
Опции темы

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