MyTetra Share
Делитесь знаниями!
Как сделать константное свойство в классе в языке C++
Время создания: 11.03.2020 16:36
Автор: Xintrea
Текстовые метки: язык, c++, gcc, g++ класс, свойство, константа, const, static, заголовочный файл
Раздел: Компьютер - Программирование - Язык C++ (Си++)
Запись: xintrea/mytetra_syncro/master/base/1583933818nzg3m2qnmm/text.html на raw.github.com

Некоторые C++ компиляторы (например, gcc/g++) не могут переварить следующую конструкцию в определении класса:



class MyClass

{

const int delayTime=1000;

...



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


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


Поэтому многие компиляторы требуют (но не всегда говорят напрямую), что бы константные члены класса обязательно были объявлены через модификатор static. Таким образом, проблема необоснованного расхода памяти решается автоматически, ибо статичный член класса существует только один для всех экземпляров класса.


Исходя из вышесказанного, почти правильное описание константного свойства класса должно выглядеть так:



class MyClass

{

static const int delayTime=1000;

...



Такое описание константы работает только в достаточно новых компиляторах, например в gcc выше 4.3.x, и может зависеть от включения опции поддержки стандарта C++11 и выше. Проблема в том, что работа с этой константой будет возможна только по значению. Если вдруг придется передать такую константу в функцию, которая принимает ссылку, то будет ошибка вида:



undefined reference to `MyClass::delayTime'

collect2: ld returned 1 exit status



Более традиционное описание константы требует описания статической константы в заголовке, не задавая ему значения, а установку значения надо делать в реализации, тем самым выделяя под staic-константу память и задавая значение. Вот так:



*.h-файл:


class MyClass

{

static const int delayTime;

...



*.cpp-файл:


const int MyClass::delayTime=1000;



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


А теперь немного веселья. C++ не был бы C++, если бы все было так однозначно. Простой вопрос не должен решаться просто! Поэтому масла в огонь подливает сам Страуструп в своем ЧаВо. Он предлагает следующий подход: описание статической константы и задание значения следует делать в описании класса, а определение константы (оно же выделение памяти) - вне класса. Вот так:



*.h-файл:


class MyClass

{

static const int delayTime=1000;

...

}



*.cpp-файл:


const int MyClass::delayTime;



В чем тут проблема? В том, что даже если не написать определение в *.cpp-части (например, программист может об этом забыть), то код будет работать. До поры до времени. Пока не придется передавать такую переменную через ссылку. Вот тогда будет сюрприз, о котором написано выше. Да... Язык C++ такой заботливый, он всегда старается поддержать ум и память программиста в тонусе! Это прекрасно, что помимо решения алгоритмической задачи программист вынужден дополнительно тренировать мозг постоянными вопросами "а не забыл ли я еще чего-нибудь где-нибудь прописать?".



Так же в этом разделе:
 
MyTetra Share v.0.59
Яндекс индекс цитирования