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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 22, средняя оценка - 4.86
frostua
0 / 0 / 0
Регистрация: 07.11.2011
Сообщений: 27
#1

Зачем нужен const при перегрузке оператора - C++

23.11.2011, 18:35. Просмотров 3127. Ответов 2
Метки нет (Все метки)

Следующий код описывает класс СТРОКА string_.
При перегрузке оператора '='
string_& string_::operator=(const string_ &str)
непонятно какова функция 'const'. Если он есть, то можно написать:
string_ A("Ivanov"), B;
B=A;
A="Petrov";

Если его нет, то A="Petrov" не скомпилируется, пишет:
binary '=' : no operator found which takes a right-hand operand of type 'const char [7]' (or there is no acceptable conversion)

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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include <iostream>
#include <string.h>
using namespace std;
 
class string_                
{
private:
    // Строка
    char* S;
    // Длина строки
    int len;  
public:
    // Конструктор по умолчанию
    // без параметров
    string_();
 
    // Перегруженный конструктор
    // с параметром
    string_(char* s); 
    
    // Конструктор копирования
    string_(const string_& s); 
    
    // Деструктор
    ~string_(){ 
        delete [] S;
    }  
 
    // Константный метод
    // возвращающий содержимое
    // строки
    const char*GetStr()const 
    { 
        return S;       
    }
    // метод позволяющий изменить содержимое
    // с помощью пользователя
    void SetStr() 
    {
        // если строка не пустая - очистить
        if(S!=NULL)
            delete[]S;
        
        // создаем массив
        // и запрашиваем у пользователя данные
        char a[256]; 
        cin.getline(a,256); 
 
        // просчитываем размер
        len=strlen(a)+1;
 
        // выделяем память
        S = new char[len];
 
        // переписываем в объект
        // введенную строку
        strcpy(S,a); 
    }
 
    // Перегрузка бинарного оператора
    string_& operator=(const string_&);
};
 
string_::string_()
{
    // Начальная инициализация
    S = NULL;       
    len = 0;
}
 
string_::string_(char* s)
{
    len = strlen(s);
    S = new char[len + 1];
    // Инициализация строкой,
    // переданной пользователем
    strcpy(S, s);           
}
 
string_::string_(const string_& s)
{
    len = s.len;
    // Безопасное копирование
    S = new char[len + 1];  
    strcpy(S, s.S);
}
 
// Функция, реализующая безопасное присваивание
string_& string_::operator=(const string_ &str)
{                               
    // Предотвращение варианта STRING = STRING; 
    // (присваивание самому себе),
    // где STRING переменная класса string                              
    if(this == &str) 
         return *this;   
    // если размеры строк не совпадают
    // или строка, в которою производится запись
    // не сформированна
    if(len != str.len || len == 0)
    {
        // Удаление старой строки
        delete [] S;
        // Вычисление новой длины строки            
        len = str.len;
        // Выделение памяти под новую строку          
        S = new char[len + 1];  
    }
 
    // Инициализация строки
    strcpy(S, str.S);          
    return *this;               
}
 
void main()
{
    string_ A("Ivanov"), B;
    B=A;
    A="Petrov";// Не компилируется если убрать сonst
    cout<<B.GetStr()<<"\n\n";
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.11.2011, 18:35
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Зачем нужен const при перегрузке оператора (C++):

От каких ошибок страхует Const при перегрузке оператора присваивания - C++
Здравствуйте. Вопрос имею теоретический. В классе A перегружается оператор присваивания, объявление выглядит так: const A operator =...

Ошибка при перегрузке оператора + - C++
Имеется класс, который представляет из себя строку и количество символов в ней. Задача - перегрузить оператор +, чтобы он складывал нам две...

Предупреждение при перегрузке оператора - C++
Есть вот такой код для созданный для обучения #include &lt;iostream&gt; using namespace std; class complex{ private: ...

Ошибка при перегрузке оператора >> - C++
Приветствую. Есть 2 класса: enum Color { white = 1, red, green, blue, yellow }; class Shape { protected: Color figureCol; ...

Ошибка при перегрузке оператора cin >> - C++
#include &lt;iostream&gt; using namespace std; /////////////////////////////////////////////////////////// class fraction { ...

& при перегрузке оператора ввода - C++
Скажите почему без &amp; не будет работать? ostream&amp; operator&lt;&lt;(ostream &amp;stream,MyClass obj) { stream&lt;&lt;obj.a&lt;&lt;endl; return stream; ...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Сыроежка
Заблокирован
23.11.2011, 18:53 #2
Цитата Сообщение от frostua Посмотреть сообщение
Следующий код описывает класс СТРОКА string_.
При перегрузке оператора '='
string_& string_::operator=(const string_ &str)
непонятно какова функция 'const'. Если он есть, то можно написать:
string_ A("Ivanov"), B;
B=A;
A="Petrov";

Если его нет, то A="Petrov" не скомпилируется, пишет:
binary '=' : no operator found which takes a right-hand operand of type 'const char [7]' (or there is no acceptable conversion)

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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include <iostream>
#include <string.h>
using namespace std;
 
class string_                
{
private:
    // Строка
    char* S;
    // Длина строки
    int len;  
public:
    // Конструктор по умолчанию
    // без параметров
    string_();
 
    // Перегруженный конструктор
    // с параметром
    string_(char* s); 
    
    // Конструктор копирования
    string_(const string_& s); 
    
    // Деструктор
    ~string_(){ 
        delete [] S;
    }  
 
    // Константный метод
    // возвращающий содержимое
    // строки
    const char*GetStr()const 
    { 
        return S;       
    }
    // метод позволяющий изменить содержимое
    // с помощью пользователя
    void SetStr() 
    {
        // если строка не пустая - очистить
        if(S!=NULL)
            delete[]S;
        
        // создаем массив
        // и запрашиваем у пользователя данные
        char a[256]; 
        cin.getline(a,256); 
 
        // просчитываем размер
        len=strlen(a)+1;
 
        // выделяем память
        S = new char[len];
 
        // переписываем в объект
        // введенную строку
        strcpy(S,a); 
    }
 
    // Перегрузка бинарного оператора
    string_& operator=(const string_&);
};
 
string_::string_()
{
    // Начальная инициализация
    S = NULL;       
    len = 0;
}
 
string_::string_(char* s)
{
    len = strlen(s);
    S = new char[len + 1];
    // Инициализация строкой,
    // переданной пользователем
    strcpy(S, s);           
}
 
string_::string_(const string_& s)
{
    len = s.len;
    // Безопасное копирование
    S = new char[len + 1];  
    strcpy(S, s.S);
}
 
// Функция, реализующая безопасное присваивание
string_& string_::operator=(const string_ &str)
{                               
    // Предотвращение варианта STRING = STRING; 
    // (присваивание самому себе),
    // где STRING переменная класса string                              
    if(this == &str) 
         return *this;   
    // если размеры строк не совпадают
    // или строка, в которою производится запись
    // не сформированна
    if(len != str.len || len == 0)
    {
        // Удаление старой строки
        delete [] S;
        // Вычисление новой длины строки            
        len = str.len;
        // Выделение памяти под новую строку          
        S = new char[len + 1];  
    }
 
    // Инициализация строки
    strcpy(S, str.S);          
    return *this;               
}
 
void main()
{
    string_ A("Ivanov"), B;
    B=A;
    A="Petrov";// Не компилируется если убрать сonst
    cout<<B.GetStr()<<"\n\n";
}
Вам уже компилятор ответил на ваш вопрос! Нужно ттолько читать внимательно сообщения вашего компилятора. Дело в том, что когда вы используете предложение вида

C++
1
    A="Petrov";
то делаются следующие действия. Первое, сначала вызывается конструктор с одним параметром string_(char* s); , а затем созданный неименованный временный объект присваивается вашему объекту A. То есть приведенный выше код соответствует коду

C++
1
    A = string_( "Petrov" );
Но проблема в том, что неименованные временные объекты могут свуязываться лишь с константной ссылкой. Поэтому когда вы убираете квалификатор const у параметра оператора присваивания, то этот топератор присваивания уже не может применяться в данном предложении, так как неконстантная ссылка не может связываться с неименованным временным объектом.

Другой пример. Допустим вы объявили константный объект

C++
1
const string_ B( "Petrov"  );
Тогда и в этом случае вы не можете писать

C++
1
A = B;
так как требуется оператор присваивания, который в качестве аргумента может принимать константные объекты. То есть его параметр должен быть объявлен с квалификатором const
frostua
0 / 0 / 0
Регистрация: 07.11.2011
Сообщений: 27
23.11.2011, 22:07  [ТС] #3
спасибо за ответ
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.11.2011, 22:07
Привет! Вот еще темы с ответами:

Преждевременный вызов деструктора при перегрузке оператора + - C++
Изначальное задание: Используя списки написать программу, поддерживающую операцию сложения двух многочленов. Собственно все работает,...

Константность ссылки в параметре при перегрузке оператора - C++
Здравствуйте! При создании класса комплексные числа операцию сложения определяю так complex operator + (complex&amp;a) { return...

Ошибка при перегрузке оператора вывода в файл - C++
Добрый день, есть такой кусок кода: #include &lt;iostream&gt; #include &lt;ostream&gt; using std::ostream; using namespace std; ...

Ошибка в перегрузке оператора - при работе с массивами - C++
Текст программы: #include &lt;iostream&gt; #include &lt;windows.h&gt; using namespace std; class array { public: array(); ...


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

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

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