Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
1

Изменение ссылки const объекта

18.10.2015, 14:22. Показов 876. Ответов 19
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый вечер,

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
#include <iostream>
using namespace std;
 
class Foo
{
private:
    int a;
    int& b;
 
public:
    Foo(const int _x) : a(_x), b(a)
    {
 
    }
 
    int f() const
    {
        return b;
    }
    void d(const int y) const
    {
        b = y;
    }
};
 
int main()
{
    const Foo a(11);
    cout << a.f() << endl;
    a.d(19);
    cout << a.f() << endl;
}
по какой причине компилятор позволяет мне изменять b ?

Как я вижу проблему - объект с пометкой const при вызове метода(позволяет вызвать только константные) не должен поменять свои данные (биты), кроме случая с mutable. Тут так и происходит - ничего не меняется. Переменная b попрежнему ссылается на переменную a. Но блин где логика?(

Добавлено через 13 часов 58 минут
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
18.10.2015, 14:22
Ответы с готовыми решениями:

int const * const foo(const int* param) const - разъясните значение квалификаторов
int const * const foo(const int* param) const -----1------2----------3----------------4 1: ?...

Создание объекта в const методе
Есть код:void OrderPart::_printDocument(const QString &amp;filename) const { QPrintDialog *dialog...

Возвращение const ссылки на временный объект
Добрый вечер, #include &lt;iostream&gt; using namespace std; struct Point { int _x; int _y; };

Const int& ссылки и константы в шаблонах
Есть шаблон. В шаблоне есть константа int. Константу надо передать в STL функцию, принимающую const...

19
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
18.10.2015, 14:30 2
Тут изменяется объект a через ссылку b, но компилятор то видимо не знает на что ссылается эта ссылка, и ничего другого в классе не изменяется, поэтому ничего криминального.
1
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
18.10.2015, 14:31 3
Эквивалентный пример с использованием указателей:
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
#include <iostream>
using namespace std;
 
class Foo
{
private:
    int a;
    int * b;
 
public:
    Foo(const int _x) : a(_x), b(&a)
    {
 
    }
 
    int f() const
    {
        return *b;
    }
    void d(const int y) const
    {
        *b = y;
    }
};
 
int main()
{
    const Foo a(11);
    cout << a.f() << endl;
    a.d(19);
    cout << a.f() << endl;
}
Вопрос: почему компилятор позволяет изменять a через указатель b ?
2
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
18.10.2015, 14:32  [ТС] 4
Так как добиться защиты? или это лежит на программисте - если он пишит так - то должен понимать, что const объект схавает это.
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
18.10.2015, 14:37 5
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
Будь-то указатель такой беды бы небыло.
Убежденный, привёл пример с указателем. Суть та же.

Добавлено через 3 минуты
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
Так как добиться защиты?
В данном случае можно объявить b ссылкой на константу: const int & b;.
2
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
18.10.2015, 14:50  [ТС] 6
Цитата Сообщение от castaway Посмотреть сообщение
В данном случае можно объявить b ссылкой на константу: const int & b;.
Тогда не возможно будет вообще менять состояние на что ссылается с любым модификатором объекта.

А вот я придумал такой вариант:

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
#include <iostream>
using namespace std;
 
class Foo
{
private:
    int a;
    int& b;
 
public:
    Foo(const int _x) : a(_x), b(a)
    {
 
    }
 
    int f() const
    {
        return b;
    }
    void d(const int y) 
    {
        b = y;
    }
    // +comment:    can't change const object state
    void d(const int) const = delete;
    
};
 
int main()
{
    const Foo a(11);
    cout << a.f() << endl;
    a.d(19);
    cout << a.f() << endl;
}


Возможно это считать за ответ? Я могу менять как мне нужно объект и его поля, но если объект константый мне просто не даст вызвать "опасные" методы и соответствующий комментарий сопровождающему юзвергу.
1
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
18.10.2015, 14:53 7
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
А вот я придумал такой вариант:
Ну так тут у тебя 25-я строка работает только в купе с const из 31-й.

Честно говоря, я не встречал таких ситуаций, и мне кажется что это просто нужно предусмотреть, так сказать, "вручную".
0
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
18.10.2015, 14:55  [ТС] 8
Так в этом и соль. Делаю с классом, что хочу - а в методы куда приходит (const Foo& obj) я знаю, что он выйдет оттуда таким же как и вошёл(как он так и его состовляющее)
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
18.10.2015, 14:56 9
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
Делаю с классом, что хочу
Как же ты делаешь с ним всё что хочешь, если экземпляр - константа?
0
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
18.10.2015, 15:00  [ТС] 10
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
#include <iostream>
using namespace std;
 
class Foo
{
private:
    int a;
    int& b;
 
public:
    Foo(const int _x) : a(_x), b(a)
    {
 
    }
 
    int f() const
    {
        return b;
    }
    void d(const int y) 
    {
        b = y;
    }
    // +comment:    can't change const object state
    void d(const int) const = delete;
    
};
 
int main()
{
    const Foo a(11);
    Foo b(11);  
    //a.d(19);
    b.d(19);
 
 
    cout << a.f() << endl;
    cout << b.f() << endl;
    
}
Я о той безопасности, что даёт 33 строка. Юзверг использующий мой класс не сможет изменить его при модификаторе const.
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
18.10.2015, 15:03 11
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
Я о той безопасности, что даёт 33 строка. Юзверг использующий мой класс не сможет изменить его при модификаторе const.
Ну тогда строки с 20-й по 25-ю включительно можно смело удалить.
0
rikimaru2013
18.10.2015, 15:05  [ТС]
  #12

Не по теме:

Всё я сдаюсь - я не смогу вам доказать что-то, так как вы не хотите воспринимать. Я пас.

0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
18.10.2015, 15:16 13
Блин. Мне кажется что ты сам не совсем понимаешь ситуацию
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
Юзверг использующий мой класс не сможет изменить его при модификаторе const.
Ок. Пользователь не сможет изменить константный объект, который ему каким-то образом предоставляется, но, допустим, внутри твоей библиотеки ты сам можешь изменять состояние объекта, так? Я правильно понял?

Добавлено через 6 минут
При если ты именно это имеешь в виду, то ты сможешь обезопасить только пользователя, но не себя, и удалённый метод тебе не поможет. В результате чего, мы возвращаемся к сообщению №4, а именно к вопросу "Так как добиться защиты?".
1
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
18.10.2015, 15:25  [ТС] 14
Я рассматриваю вопрос - насколько я в безопасносте отдавая (const Foo& obj) - уверен ли я, что объект и его состовляющие не будут менятся внутри данной функции. Ответ: всё зависит от того: какие константные методы ты предоставишь в интерфейсе класса и будут ли они менять состовляющие.

Я понял мыслю, что castaway, вы несёте. Хочешь обезопасить себя? Пересмотри константный интерфейс на наличие "пробоин" в корабле и всё.
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
18.10.2015, 15:30 15
rikimaru2013, я просто хочу сказать что это не выход. Вот и всё.
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
18.10.2015, 16:18 16
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
по какой причине компилятор позволяет мне изменять b ?
по той причине, что на языке с++ ссылки внезапно не обладают квалификатором const.

вот указатели бывают константами.
и тогда, такой указатель нельзя перенацелить.

для ссылок же это не имеет смысла,
потому что они по своей природе своего рода константы.



C++
1
2
3
4
5
6
7
void d(const int y) const
{
    b = y; //<--- здесь вы не можете перенацелить ссылку
    // (хотя вы её в любом случае не можете перенацелить)
    // но можете изменять объект, на который ссылается ссылка
    // потому что в классе она объявлена, как мутабельная
}
Добавлено через 2 минуты
Цитата Сообщение от castaway Посмотреть сообщение
поэтому ничего криминального.
экземпляр класса был рожден константным.
следовательно все его данные члены
так же получаются рождены как константы.

а изменение состояние объекта,
который был рожден как константа - есть UB.

так что проблема существует.

Добавлено через 4 минуты
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
Возможно это считать за ответ?
годное решение
1
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
18.10.2015, 16:52  [ТС] 17
Цитата Сообщение от hoggy Посмотреть сообщение
годное решение
я просто пришёл к новому выводу как писал, castaway, "зачем писать строку"
C++
1
2
 // +comment:    can't change const object state
    void d(const int) const = delete;
если без неё попрожнему компилятор сообщит нам, что void d() не const и вызывать его нечего нам.
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
18.10.2015, 17:41 18
Цитата Сообщение от hoggy Посмотреть сообщение
экземпляр класса был рожден константным.
Честно говоря, в первом сообщении я заметил это только сейчас.

Цитата Сообщение от hoggy Посмотреть сообщение
годное решение
Так а в чём выгода? Если я закомментирую 25-ю строку в 10-м сообщении, то пример всё-равно не скомпилируется. Какой смысл менять шило на мыло?
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
18.10.2015, 22:28 19
Цитата Сообщение от castaway Посмотреть сообщение
Так а в чём выгода? Если я закомментирую 25-ю строку в 10-м сообщении, то пример всё-равно не скомпилируется. Какой смысл менять шило на мыло?
вот я несколько раз говорил людям,
что все эти квалификаторы и модификаторы доступа нужны человекам,
а не компилятору.
все эти материи предназначены для гарантий инкапсуляции и инвариантов.

почему мы нечто делаем приватным?
потому что существует угроза:
прямое вмешательство внешней стороны может повредить механизм.
а так, сеттеры проконтролируют, что все правильно.

аналогично и с квалификаторами:
почему мы возвращаем константную ссылку?
мы хотим сказать: пожалуйста, читайте.
но гайки что б не подкручивали.

подкручивание гаек может повредить механизм.


теперь вернемся к нашим баранам:

выгода в том, что намерения разработчика явным образом подчеркиваются.
мы сообщаем читателю кода, что константной версии метода не должно быть.

мы сделали это настолько явно, что читатель сразу же насторожиться:
наверное это же не спроста?

если вы просто закомментируете 25-ю строчку в 10-м сообщении,
то тема вернется на исходную позицию (см сабж в первопосте):

в будущем, программист не увидит предупреждающего явного запрета на константную версию метода,
и может ничайно реализовать её, поимев ссылку, для которой не отработает защита квалификатора.
компилятор не предупредит об опасности, и все - UB, приплыли.
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
19.10.2015, 00:18 20
hoggy, да я всё это прекрасно понимаю, и оставил не мало сообщений в этой теме со своими доводами и выводами, но если объект априори - константа, то какой смысл во всех этих манипуляциях!?
Наверное мы говорим немного о разном, и, возможно, преследуем немного разные цели...
0
19.10.2015, 00:18
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
19.10.2015, 00:18
Помогаю со студенческими работами здесь

Изменение const-переменной
Имеется следующий код: #include &lt;iostream&gt; int main() { using namespace std; cout...

Как вызвать прегруженный const метод для статического объекта
class A { public: A() { cout &lt;&lt; &quot;A()&quot; &lt;&lt; endl; } ~A() { cout &lt;&lt; &quot;~A()&quot; &lt;&lt; endl; } void...

char operator[](unsigned short offset) const; // что означает const?
Собстенно вопрос уже озвучен :).

Что это bool operator== (const CLASS&) const;
Что это? class CLASS { public: bool operator== (const CLASS&amp;) const; ...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru