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

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

Войти
Регистрация
Восстановить пароль
 
 
Тамика
Котовчанин
870 / 450 / 143
Регистрация: 16.02.2010
Сообщений: 2,954
Записей в блоге: 27
#1

No init for const! - C++

23.07.2015, 10:21. Просмотров 561. Ответов 21
Метки нет (Все метки)

Доброе утро, котаны!
Вопрос - в джаве есть возможность сделать такую штуку
Java
1
2
final boolean someBool;
someBool  = true;
То есть объявить константу, а потом её инициализировать. Правда, только один раз. В плюсах такое не скомпилиться.
C++
1
2
3
4
5
6
7
int main()
{
    const int temp;
    std::cin >> temp;
 
    system("pause>>null");
}
Чистый интерес - возможно ли как-то это обойти? То есть, объявить константу не заинитив?
Не спрашивайте для чего это нужно. Наверное ни для чего. Просто интерес.)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.07.2015, 10:21     No init for const!
Посмотрите здесь:

Lambda init capture by const reference - C++
Всем привет. Почему не получается добиться следующего поведения: auto main() -> int { int ival = 0; () { // Need...

Разница между объявлениями const Person p1 и Person const p1 - C++
Всем привет. Собственно весь вопрос уместился в заголовок: в чем разница между объявлениями const Person p1 и Person const p1, если...

Методы init() и dispose() - теория - C++
Всегда интересовало, зачем существуют эти методы? Допустим, есть некоторый объект класса и в коде видим: x = new myClass(); ...

функция вида init( struct ****) - segmentation fault - C++
Прошу помочь, уже всю голову сломал. Дан следующий код struct square { bool is_rect; int is_side; struct square...

Что делает оператор init в данной ситуации (работа с двумерными массивами) - C++
Есть фрагмент кода C++. const int ROWS = 10, COLUMNS = 10; int matrix; init(&matrix); int temp, sum = 0;

Int* const или const int*? - C++
class A { public: A() : x(777) {} int* const GetX() { return &x; }

const - C++
объясните мне пожалуйста почему в конце объявления функций нужно писать const? точнее почему в данной ситуаций.. bool empty() const; ...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6443 / 3082 / 306
Регистрация: 04.12.2011
Сообщений: 8,486
Записей в блоге: 4
23.07.2015, 11:39     No init for const! #16
Цитата Сообщение от Тамика Посмотреть сообщение
Хм... Ну это то, про что говорил zss, я правильно поняла?
абсолютно. Вообще обмануть компилятор можно, но если честно то нельзя инициализировать константы и ссылки вне объявления. В классе и со списком, - можно.
А ошибок наделать легко и без хаков. Вот древняя история
Цитата Сообщение от из упанишад
После шести часов тяжелейших мучений он нашёл ошибку. Она состояла в том что при копипасте были перепутаны 2 переменные с именами длинными и отличающимися одним символом!
"Слава те господи!" - тихо пробормотал он. Монитор закачался, экран треснул, а системный блок ещё долго эхом отражал :"твою мать..., твою мать..., твою мать..."

Но если очень хочется то можно.
Croessmah
Модератор
Эксперт CЭксперт С++
13052 / 7315 / 814
Регистрация: 27.09.2012
Сообщений: 18,052
Записей в блоге: 3
Завершенные тесты: 1
23.07.2015, 11:41     No init for const! #17
Информация с стандарта?
const - просто квалификатор, который показывает что переменную менять бы не надо, он не гарантирует то, что сами данные константны. Для примера:
C++
1
2
3
4
void foo ( const int & x )
{
    //работаем с x
}
Для функции переменная x - просто "неизменяемая переменная", которая может быть константой, а может и не быть.
rikimaru2013
C++ Game Dev
2419 / 1113 / 240
Регистрация: 30.11.2013
Сообщений: 3,660
23.07.2015, 11:42     No init for const! #18
Цитата Сообщение от Тамика Посмотреть сообщение
А какие проблемы могут быть в таком случае?
Кажись никаких, а вот
C++
1
2
3
4
5
6
7
8
9
10
void change_me(const int& a)
{
  const_cast<int&>(a) = 3;
}
 
int main()
{
 const int a = 5;
  change_me(a);
}
Тут UB - компилятор мог закэшировать число 5, и он в нужный момент может не ожидать, что там не 5 )))))
SatanaXIII
Супер-модератор
Эксперт С++
5602 / 2636 / 242
Регистрация: 01.11.2011
Сообщений: 6,495
Завершенные тесты: 1
23.07.2015, 11:42     No init for const! #19
Типа того:
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
struct s_s
{
    const int const_val;
    s_s()
      :const_val(0)
      {}
} s;
 
int main()
{
  int *ptemp;
  int val_temp;
 
 
  std::cin >> val_temp;
 
 
  ptemp = const_cast< int* > ( &s.const_val );
  *ptemp = val_temp;
 
 
  cout << s.const_val;
 
  return 0;
}
upd
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
struct s_s
{
    const int const_val;
    s_s()
      :const_val(0)
      {}
} s;
 
int main()
{
  int *ptemp = const_cast< int* > ( &s.const_val );
 
  std::cin >> *ptemp;
 
  cout << s.const_val;
 
  return 0;
}
Croessmah
Модератор
Эксперт CЭксперт С++
13052 / 7315 / 814
Регистрация: 27.09.2012
Сообщений: 18,052
Записей в блоге: 3
Завершенные тесты: 1
23.07.2015, 12:04     No init for const! #20
Цитата Сообщение от Тамика Посмотреть сообщение
А какие проблемы могут быть в таком случае?
Ну, собственно
7.1.6.1

2. [ Note: Declaring a variable const can affect its linkage (7.1.1) and its usability in constant expressions (5.20). As described in 8.5, the definition of an object or subobject of const-qualified type must specify an initializer or be subject to default-initialization. —end note ]

3. A pointer or reference to a cv-qualified type need not actually point or refer to a cv-qualified object, but it is treated as if it does; a const-qualified access path cannot be used to modify an object even if the object referenced is a non-const object and can be modified through some other access path. [ Note: Cv-qualifiers are supported by the type system so that they cannot be subverted without casting (5.2.11). —end note ]
DrOffset
7058 / 4199 / 949
Регистрация: 30.01.2014
Сообщений: 6,965
23.07.2015, 13:28     No init for const! #21
Цитата Сообщение от Тамика Посмотреть сообщение
То есть объявить константу, а потом её инициализировать. Правда, только один раз.
Можно проэмулировать. Правда частично уже в рантайме.

Вот тебе пример "на поиграться":
Кликните здесь для просмотра всего текста

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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include <iostream>
#include <stdexcept>
#include <string>
 
static struct default_init_tag_ {} default_init_tag;
 
template <typename T>
struct const_var
{
    template <typename V>
    const_var(V const & x) 
        : wasInit_(false) 
    {
        init(x);
    }
    const_var(const_var const & x) 
        : wasInit_(false)
    {
        if(x.wasInit())
        {
            init(x);
        }
    }
    const_var(default_init_tag_) 
        : wasInit_(false)
    {
        init();
    }
    const_var() 
        : wasInit_(false)
    { }
    
    const_var const & operator=(const_var const & x) const
    {
        if(this != &x && x.wasInit())
        {
            init(x);
        }
        return *this;
    }
    template <typename V>
    const_var const & operator=(V const & x) const
    {
        init(x);
        return *this;
    }
    template <typename V>
    const_var const & operator=(const_var<V> const & x) const
    {
        if(this != &x && x.wasInit())
        {
            init(x);
        }
        return *this;
    }
    const_var const & operator=(default_init_tag_) const
    {
        init();
        return *this;
    }
    
    operator T const &() const
    {
        if(wasInit_)
        {
            return var_.value;
        }
        throw std::logic_error("attempt to get the value from an uninitialized object");
    }
    
    ~const_var()
    {
        if(wasInit_)
        {
            var_.value.~T();
        }
    }
 
    bool wasInit() const
    {
        return wasInit_;
    }
    
private:
    template <typename ...Args>
    void init(Args const & ...v) const
    {
        if(!wasInit_)
        {
            ::new(&var_.value) T(v...);
            wasInit_ = true;
        }
        else
        {
            throw std::logic_error("re-initialization for a final object");
        }
    }
    
    mutable union storage
    {
        char data[sizeof(T)];
        T    value;
        
        storage()  {}
        ~storage() {}
        
    } var_;
    mutable bool wasInit_;
};
 
template <typename T>
using final = const const_var<T>;
 
int main()
{
    {
        final<std::string> a; // no init
        
        //std::string b1 = a; // get noninit value, error
        
        a = "test1"; // init
        
        std::string b2 = a; 
        
        std::cout << b2 << '\n';
        
        //a = "test"; // re-init, error
    }
    
    {
        final<std::string> a = "test2"; // init
        
        //a = "test"; // re-init, error
        
        std::string b1 = a;
        
        std::cout << b1 << '\n';        
    }
    
    {
        final<std::string> a = default_init_tag; // init default
        
    }
    
    {
        final<std::string> a; // no init
        
        a = default_init_tag; // init default
    }
}

http://rextester.com/FAEY25254

PS. Написано исключительно для поддержания разговора. Претензии по реализации не принимаются, ввиду отладки в онлайн-редакторе и практически полной бесполезности на практике (в с++).
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.07.2015, 13:56     No init for const!
Еще ссылки по теме:

static const - C++
объясните, пожалуйста, вот такую странную конструкцию (накопал в старой проге): после #include идет следующее: static const char...

const function - C++
Здравствуйте, совсем забыл не напомните, что меняется в функции в зависимости от расположения const: Например: const int const...

const double * - C++
Доброго всем времени суток. Подскажите, в записи double my_func(const double *A); Константным будет указатель или массив?

Const параметр - C++
зачем пишут class Sm{ public: Sm(const Sm&amp;){}; // same with operator@ }; если ссылка и так константа. достаточно Sm&amp;. или я...

static const? - C++
если мне нужна константа в классе, как ее лучше объявить со static или без? разница будет только в том, что со статиком мне можно будет...


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

Или воспользуйтесь поиском по форуму:
hoggy
6426 / 2644 / 458
Регистрация: 15.11.2014
Сообщений: 5,834
Завершенные тесты: 1
23.07.2015, 13:56     No init for const! #22
Цитата Сообщение от DrOffset Посмотреть сообщение
PS. Написано исключительно для поддержания разговора. Претензии по реализации не принимаются, ввиду отладки в онлайн-редакторе и практически полной бесполезности на практике (в с++).
чоткий сказ!

Цитата Сообщение от Тамика Посмотреть сообщение
Вопрос - в джаве есть возможность сделать такую штуку
в плюсах такую штуку делать нельзя, и точка.

все эти мозговыверты - это лишь имитация.

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

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

честных способов обойти это - не существует.

а нечестные на самом деле лишь косят под константу,
но на деле "настоящими" константами не являются.

либо это уже за пределами UB.

тобишь, городить такой огород просто нет смысла.
Yandex
Объявления
23.07.2015, 13:56     No init for const!
Ответ Создать тему
Опции темы

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