Kuzmich
Гость
|
|
« : 21-01-2004 06:14 » |
|
VOID CALLBACK proc(HWND hwnd, UINT, UINT, DWORD) { static BOOL b = FALSE; if(b){ SetWindowText(hwnd, "Title 1"); } else{ SetWindowText(hwnd, "Title 2"); } b=!b; } что означает static BOOL b = FALSE; ? глобальная переменная ? почему нельзя ее просто объявить как глобальную ?
|
|
« Последнее редактирование: 23-11-2007 18:55 от Алексей1153++ »
|
Записан
|
|
|
|
GlukSoft
Главный специалист
Offline
Пол:
|
|
« Ответ #1 : 21-01-2004 06:46 » |
|
Kuzmich, значит память под нее выделится при старте программы (при этом будет инициализирована нулем) и будет удалена только при завершении работы программы. Объявленно в данном случае для того, чтобы сохранить значение между вызовами процедуры.
|
|
|
Записан
|
Fatal error C1: Brain expected
|
|
|
NetRaider
Гость
|
|
« Ответ #2 : 21-01-2004 06:48 » |
|
VOID CALLBACK proc(HWND hwnd, UINT, UINT, DWORD) { static BOOL b = FALSE; if(b){ SetWindowText(hwnd, "Title 1"); } else| SetWindowText(hwnd, "Title 2"); } b=!b; } что означает static BOOL b = FALSE; ? глобальная переменная ? Нет, не глобальная - 'static BOOL b = FALSE;' означает, что переменная b имеет статический класс памяти(static storage duration). Т.е. существует в течении всего времени выполнения программы и ее значение сохраняется между вызовами функции 'proc'. почему нельзя ее просто объявить как глобальную ?
Можно и как глобальную.
|
|
« Последнее редактирование: 23-11-2007 18:57 от Алексей1153++ »
|
Записан
|
|
|
|
SlavaI
Главный специалист
Offline
|
|
« Ответ #3 : 21-01-2004 06:49 » |
|
Если переменная static в функции то ее значение не изменяется между вызовами функций, то есть переменная не стековая. По сути- это глобальная переменная(что не означает что она в той же области памяти что и глобальные переменные, хотя чаще всего это так), но видима она только из функции, где она объявлена и соотвественно может изменяться только в ней, а глобальную может менять кто угодно, что может нарушить логику работы ф-ции, может она там счетчик вызовов хранит и менять должна его только она.
|
|
|
Записан
|
|
|
|
SlavaI
Главный специалист
Offline
|
|
« Ответ #4 : 21-01-2004 06:59 » |
|
Николай, значит память под нее выделится при старте программы
с этим почти согласен, хотя необязательно выделять сразу при старте как для глобальных, хотя обычно это так. (при этом будет инициализирована нулем)
Не согласен. Инициализация- это вызов конструктора, для статических перемнных в функциях его вызовут только при первом вызове функции.
|
|
|
Записан
|
|
|
|
GlukSoft
Главный специалист
Offline
Пол:
|
|
« Ответ #5 : 21-01-2004 07:25 » |
|
SlavaI, т.к. доступ к переменной осуществляется только из функции, то главное, что переменная будет существовать перед первым вызовом и при первом вызове будет равна нулю, и что переменная будет существовать между вызовами. Остальное в данном случае не так уж и важно (мне так кажется ).
|
|
|
Записан
|
Fatal error C1: Brain expected
|
|
|
NetRaider
Гость
|
|
« Ответ #6 : 21-01-2004 07:45 » |
|
Николай, (при этом будет инициализирована нулем)
Не согласен. Инициализация- это вызов конструктора, для статических перемнных в функциях его вызовут только при первом вызове функции. Верно только для объектов, требующих динамическую инициализацию. В случае статической инициализации переменной будет присвоено значение до начала выполнения функции, в которой она определена. И в любом случае сначала будет выполнена zero-initialization.
|
|
|
Записан
|
|
|
|
GlukSoft
Главный специалист
Offline
Пол:
|
|
« Ответ #7 : 21-01-2004 08:03 » |
|
NetRaider, так я в последнем комментарии об этом и написал .
|
|
|
Записан
|
Fatal error C1: Brain expected
|
|
|
SlavaI
Главный специалист
Offline
|
|
« Ответ #8 : 21-01-2004 08:38 » |
|
Верно только для объектов, требующих динамическую инициализацию.
А вот эту мысль разъясните. Я так понял имеется в виду то что базовые типы С в С++ не являются классами, а поэтому и не имеют (формально в виде ф-ции) конструктора, весь их конструктор(для глобальных и стаических переменных) заключается в инициализации нулем, что было и в С. И в любом случае сначала будет выполнена zero-initialization.
Вполне возможно(для классов). А судя по коду VC7 так и есть- сначала нулями потом конструктором. Конструктор(базовые типы С не рассматриваем) вызовут при входе в функцию, обычно компиляторы создают глобальную переменную и вставляют ее проверку при вызове ф-ции, если она например больше нуля - не вызывать конструктор статических переменных, если ноль- значит первый вызов функции, вызвать конструкторы, и увеличить глобальную переменную.
|
|
|
Записан
|
|
|
|
NetRaider
Гость
|
|
« Ответ #9 : 21-01-2004 09:35 » |
|
Верно только для объектов, требующих динамическую инициализацию.
А вот эту мысль разъясните. Я так понял имеется в виду то что базовые типы С в С++ не являются классами, а поэтому и не имеют (формально в виде ф-ции) конструктора, весь их конструктор(для глобальных и стаических переменных) заключается в инициализации нулем, что было и в С. Основные типы С++ являются POD-типами: 3.9/10 Arithmetic types (3.9.1), ... enumeration types, pointer types and pointer to member types (3.9.2),... and cv-qualified versions of these types are collectively called scalar types. Scalar types, POD - struct types, POD - union types (clause 9), arrays of such types and cv-.... are collectively called POD types. Статический объект POD типа может быть проинициализирован разными способами, например: 1) 'static int a = 10;' 2) 'static int a = foo()' Для случаев типа (1) инициализация выполняется до того, как управление попадет в блок, где определены переменные. Во втором случае (инициализация посредством функции, либо конструктором) мы имеем динамическую инициализацию. Такие объеты должны быть инициализированны не просто при первом вызове, а в тот момент, когда выполняется фрагмент кода, в котором определен объект.
|
|
|
Записан
|
|
|
|
Kuzmich
Гость
|
|
« Ответ #10 : 21-01-2004 12:13 » |
|
все понял, всем большое СПАСИБО
|
|
|
Записан
|
|
|
|
|
Serega
Гость
|
|
« Ответ #12 : 26-01-2004 20:22 » |
|
Это значит что переменная b будет одна для всех обьектов класса A, причем как к переменной так и к функции мы имеем доступ (а точнее не имеем, т.к. они private, надо public написать ) без создания экземпляра класса A::b = 3; int i = A::somefunc(); A::b = A::somefunc();
|
|
« Последнее редактирование: 23-11-2007 19:00 от Алексей1153++ »
|
Записан
|
|
|
|
Pu
Большой босс
Offline
78
|
|
« Ответ #13 : 26-01-2004 21:15 » |
|
и к сказанному . Статические переменные класса необходимо инитить за пределами класса. int A::b = 0; // компилятор иначе дает Error
по статическим переменным объявленным внутри функций - область видимости будет ограничена только функцией - в этом и различие - имя Глобальной переменной будет видно в пределах файла.
|
|
|
Записан
|
Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать. (с) Артур Джонс
|
|
|
lapulya
Молодой специалист
Offline
|
|
« Ответ #14 : 27-01-2004 09:43 » |
|
Немного не точно и к сказанному . Статические переменные класса необходимо инитить за пределами класса. int A::b = 0; // компилятор иначе дает Error
компилятор то скажет что все отлично, а вот компоновщик будет ругаться, потому как переменная объявлена но не определена (память под нее не выделена) т.е. definition был сделан, а вот declaration нет...
|
|
|
Записан
|
С уважением Lapulya
|
|
|
Pu
Большой босс
Offline
78
|
|
« Ответ #15 : 27-01-2004 10:10 » |
|
да , согласен чуть не точно, действительно компоновщик. SERV_EXE error LNK2001: unresolved external symbol "private: static void * CSM_Lx::m_hEventTimer" (?m_hEventTimer@CSM_Lx@@0PAXA)
|
|
|
Записан
|
Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать. (с) Артур Джонс
|
|
|
Артем
Опытный
Offline
Пол:
Beware the wolf in sheep's clothing.
|
|
« Ответ #16 : 25-05-2007 08:20 » |
|
Статическая переменная внутри функции-члена класса (нестатичной функции) -- общая для всех экземпляров??? class MyClass { public: int f(); };
int MyClass::f() { static test = 0; test++; return test; }
int main() { MyClass M1; MyClass M2;
int m1 = 0; int m2 = 0;
m1 = M1.f(); m1 = M1.f();
m2 = M2.f(); } m2 = 3 !!!! Такое поведение прописано стандартом?
|
|
« Последнее редактирование: 25-05-2007 08:22 от Артем »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #17 : 25-05-2007 08:41 » |
|
Артем, да, общая
как и код метода (в данном случае - конструктора) - тоже общий для всех экземпляров
|
|
|
Записан
|
|
|
|
Антон (LogRus)
|
|
« Ответ #18 : 25-05-2007 13:18 » |
|
И в любом случае сначала будет выполнена zero-initialization.
Вот это не понял. Можно по подробней. Что значит zero-initialization?
|
|
|
Записан
|
Странно всё это....
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #19 : 25-05-2007 13:51 » |
|
LogRus, он имеет в виду - нулями заполнится . Хотя написано ли это в стандарте ? )
|
|
|
Записан
|
|
|
|
lapulya
Молодой специалист
Offline
|
|
« Ответ #20 : 27-05-2007 23:13 » |
|
Написано
|
|
|
Записан
|
С уважением Lapulya
|
|
|
|