class A{
public:
static const int arr[];
};
const int A::arr[] = {0,1,2,3,4};
Показаны сообщения с ярлыком const. Показать все сообщения
Показаны сообщения с ярлыком const. Показать все сообщения
пятница, 8 апреля 2011 г.
55. Как объявить в классе и проинициализировать статический константный массив?
Как и другие статические константы
четверг, 24 марта 2011 г.
51. Влияет ли наличие целочисленных констант-полей на размер класса?
Конечно, ведь каждый объект будет хранить свою константу. Но если константа static, то она будет храниться в одном экземпляре для всех объектов класса, и не повлияет на размер объекта.
пятница, 18 февраля 2011 г.
43. Каким образом разрешается инициализировать константные поля в классе?
Я уже насписал в ответе на "42. Как объявить константу в классе? Можно ли объявить дробную константу?". Вкратце:
К интегральным типам относятся char, short, int и long.
Есть еще один способ создания констант в классе, это enum hack. Изменим пример из ответа на 42-й вопрос.
class A{
const T i;
static const T i1 = 1; /* Если T - неинтегральный тип, может не сработать */
static const T i2; /* Для неинтегральных типов здесь только объявить, а проинициализировать позже */
A():i(const_value){}
};
const T A::i2 = const_value;
К интегральным типам относятся char, short, int и long.
Есть еще один способ создания констант в классе, это enum hack. Изменим пример из ответа на 42-й вопрос.
class Year {
/*...*/
enum {MIN_YEAR = 1900, MAX_YEAR = 2100};
/*...*/
}
четверг, 17 февраля 2011 г.
42. Как объявить константу в классе? Можно ли объявить дробную константу?
Сначала нужно подумать, что может означать "константа в классе". Попробую использовать относительно реальные примеры, а не мой любимый "class A" :)
Первый случай
Допустим, мы пишем класс Polygon (многоугольник). Мы хотим, чтобы количество вершин задавалось при создании объекта.
Второй случай
У нас есть класс Year, и мы хотим, чтобы задаваемый год не выходил за границы диапазона
Можно ли объявить дробную константу?
Вопрос относится ко второму случаю, с первым (класс Polygon) все нормально.
Дробную объявить можно, но проинициализировать только аналогично способу инициализации DEFAULT_YEAR. Однако в спецификации нет явного запрета на:
Первый случай
Допустим, мы пишем класс Polygon (многоугольник). Мы хотим, чтобы количество вершин задавалось при создании объекта.
class Polygon{
int vertexes;
public:
Polygon(int v):vertexes(v){}
}
Таким образом, при создании экземпляра будет необходимо задать количество вершин, так как конструктора по умолчанию уже нет. Все хорошо, но в какой-нибудь функции-члене можно ненароком изменить vertexes, а мы этого не хотим. Тогда и добавляем модификатор const.const int vertexes;
Значение такой переменной можно задать только в списке инициализации конструктора, как и сделано в примере. А вот так даже и не пытайтесь:Polygon(int v){vertexes = v;} /*ошибка*/
см. также Страуструп 10.4.6.1. "Необходимая инициализация членов"Второй случай
У нас есть класс Year, и мы хотим, чтобы задаваемый год не выходил за границы диапазона
const int MIN_YEAR = 1900;
const int MAX_YEAR = 2100;
const int DEFAULT_YEAR = 2011;
class Year{
int year;
public:
Year(int y);
};
Year::Year(int y){
if(y < MIN_YEAR || y > MAX_YEAR){
y = DEFAULT_YEAR;
}else{
year = y;
}
}
Хорошо было бы, если класс не молчал, а как-то предупреждал о выходе за пределы, например генерировал исключение, но это пока не важно. Я хочу поместить эти константы в класс. Способ из предыдущего примера явно не подходит. Тут явно напрашивается связь со статическими членами. Так и есть, можно использовать статические константные члены.class Year{
int year;
static const int MIN_YEAR = 1900;
static const int MAX_YEAR = 2100;
static const int DEFAULT_YEAR;
public:
Year(int y);
};
const int Year::DEFAULT_YEAR = 2011;
Year::Year(int y){
if(y < MIN_YEAR || y > MAX_YEAR){
year = DEFAULT_YEAR;
}else{
year = y;
}
}
Обратили внимание, что DEFAULT_YEAR проинициализирован за пределами класса? Да, можно и так. А с дробными, согласно спецификации, только так.Можно ли объявить дробную константу?
Вопрос относится ко второму случаю, с первым (класс Polygon) все нормально.
Дробную объявить можно, но проинициализировать только аналогично способу инициализации DEFAULT_YEAR. Однако в спецификации нет явного запрета на:
class A{
static const double PI = 3.1415;
}
MinGW на это не ругается, VS не знаю. Почему так сложно с дробными? Я и сам не понял, можно почитать ветку форума, там вроде все выяснили.
суббота, 26 сентября 2009 г.
Константы
У Эккеля не зря целая глава выделена под константы. В этой теме много интересного. Сейчас я хочу создать константу и подкопаться к ней через указатели.
const int a = 1;
int b;
cout << &a << &b; //У меня, при запусках, b всегда имеет адрес меньше(на 4 байта), чем a.
int* p = (&b+1); //Это адрес константы a
cout << *p //1
*p = 2; //Меняем
cout << a << endl << *p; //1 2
Вроде поменяли, однако a осталось прежним, но по ее адресу лежит число 2. Дело в том, что компилятор просто заменяет все вхождения a на 1, и обычно для этого не выделяет память. Но когда мы написали &a, компилятор все-таки выделил память для нее и записал туда значение. Но все-равно перед компиляцией заменил в коде a на 1. Память вроде бы пропадает впустую, ее даже можно изменить.
const int a = 1;
int b;
cout << &a << &b; //У меня, при запусках, b всегда имеет адрес меньше(на 4 байта), чем a.
int* p = (&b+1); //Это адрес константы a
cout << *p //1
*p = 2; //Меняем
cout << a << endl << *p; //1 2
Вроде поменяли, однако a осталось прежним, но по ее адресу лежит число 2. Дело в том, что компилятор просто заменяет все вхождения a на 1, и обычно для этого не выделяет память. Но когда мы написали &a, компилятор все-таки выделил память для нее и записал туда значение. Но все-равно перед компиляцией заменил в коде a на 1. Память вроде бы пропадает впустую, ее даже можно изменить.
Подписаться на:
Сообщения (Atom)