Hooter
|
|
« : 02-08-2006 03:21 » |
|
Вот такой код: class A { public: A() {}; ~A() {}; static int f(); };
int A::f() { int a = 10; return a; }
int main (int argc, char **argv) { A a; int b = A::f(); int c = a.f();
return c; }
Мне почему-то всегда казалось, что такая форма вызова статической функции int c = a.f();
недопустима. Однако, gcc такой код компилирует без ошибок. На MSVC и Borlande не проверял. Стандарт С++ мне сейчас тоже недоступен. Подскажите, люди добрые, как такое может быть? Неужели, это не сон?
|
|
|
Записан
|
|
|
|
zubr
Гость
|
|
« Ответ #1 : 02-08-2006 03:45 » |
|
Широкие массы (и, как я выяснил на собственном горьком опыте, даже разработчики компиляторов C++) почти не знают о том, что с помощью селекторов можно вызывать статические функции класса и обращаться к статическим переменным класса. Следующий фрагмент верен, хотя бедные читатели вашей программы придут в такое замешательство, что подобное можно проделывать только в последний день перед увольнением: Foo f; f.Gfn(); // То же, что и Foo::GFn(); Это выдержка из книги Джеффа Элджера "C++"
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #2 : 02-08-2006 07:35 » |
|
Подскажите, люди добрые, как такое может быть? А что здесь странного? Объект - экземпляр класса. Почему же нельзя вызвать статический метод? Другое дело, что не рекомендуется так писать, чтобы не путать себя и других читателей кода.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
Hooter
|
|
« Ответ #3 : 02-08-2006 15:15 » |
|
Широкие массы ... почти не знают о том, что... Спасибо Видимо, теперь я уже не отношусь к широким массам ;( Мне понравилась вот такая конструкция: void *p = 0; b = ((A *)p)->f();
И ведь работает Чтобы враги не догадались... подобное можно проделывать только в последний день перед увольнением
Однако, разработчики библиотеки qt увольняться не собираются, а такие штуки в коде встречаются довольно часто zubr, dimka, спасибо за ответы.
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #4 : 02-08-2006 15:43 » |
|
Hooter, это вызов статического метода такой?.. Мда...
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #5 : 02-08-2006 16:04 » |
|
Вот, говорят, в исходниках от Microsoft видели такую строчку: if(this == NULL) ...
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #6 : 02-08-2006 17:32 » |
|
dimka, ) там и не такое, говорят, видели ) это, наверное, для будущих технологий - так сказать глюк в будущее )
|
|
« Последнее редактирование: 02-08-2006 17:36 от Алексей1153 »
|
Записан
|
|
|
|
nop
Гость
|
|
« Ответ #7 : 04-08-2006 06:28 » |
|
Можно и так struct A { static void f(){}
};
int main() { A a; a.A::f(); // и так (из-за injected name) a.A::A::f();
// и вот так A::A::A::A::f();
}
|
|
|
Записан
|
|
|
|
Alex437
Гость
|
|
« Ответ #8 : 10-08-2006 06:37 » |
|
А еще так бывает class A { public: static A a; static int x; }; int A::x = 0;
void main() { A my_a; my_a.a.a.a.a.a.a.a.a.a.a.x = 75; cout << my_a.a.a.a.a.x << endl; }
|
|
|
Записан
|
|
|
|
nikedeforest
|
|
« Ответ #9 : 10-08-2006 07:03 » |
|
Извращенцы
|
|
|
Записан
|
ещё один вопрос ...
|
|
|
Serg79
|
|
« Ответ #10 : 10-08-2006 08:31 » |
|
Вот, говорят, в исходниках от Microsoft видели такую строчку: if(this == NULL) ... Кстати, я что то подобное видел и в исходниках ядра LINUX. Там то же, почему то, в некоторых местах проверяется равенство с НУЛЕМ. Для чего, они это делают , сложно сказать.
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #11 : 10-08-2006 09:20 » |
|
Для чего, они это делают , сложно сказать. Люди утверждают, что иногда метод объекта "сиротеет" - вдруг обнаруживает, что объекта уже нет, а сам метод ещё выполняется... Может в параллельных потоках... Не знаю. Проблема в том, что после удаления объекта подразумевается последующая запись в указатель значения NULL, а вот кто это сможет сделать для this...
|
|
« Последнее редактирование: 10-08-2006 09:22 от dimka »
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
nikedeforest
|
|
« Ответ #12 : 10-08-2006 09:36 » |
|
Проблема в том, что после удаления объекта подразумевается последующая запись в указатель значения NULL, а вот кто это сможет сделать для this...
Деструктор?! нельзя ли поступить в деструкторе так? this=NULL;
Если можно, то по сути - это ответ на твой вопрос, или нет?
|
|
|
Записан
|
ещё один вопрос ...
|
|
|
LP
Помогающий
Offline
|
|
« Ответ #13 : 10-08-2006 09:39 » |
|
Я видел такое в ASSERT'ах. ASSERT(this != NULL); Такой ассерт сработает, в случае MyClass* p = new MyClass(); ... // работаем с p delete p; p = NULL; p->mem_fun(1);
|
|
« Последнее редактирование: 19-12-2007 19:14 от Алексей1153++ »
|
Записан
|
Если эта надпись уменьшается, значит ваш монитор уносят
|
|
|
Serg79
|
|
« Ответ #14 : 10-08-2006 11:25 » |
|
Для чего, они это делают , сложно сказать. Люди утверждают, что иногда метод объекта "сиротеет" - вдруг обнаруживает, что объекта уже нет, а сам метод ещё выполняется... Может в параллельных потоках... Не знаю. Проблема в том, что после удаления объекта подразумевается последующая запись в указатель значения NULL, а вот кто это сможет сделать для this... Все это хорошо, но только ядро LINUX-а написанно на чистом "C". Я так понимаю, что это делается для того что бы было легче читать исходники. А компилятор на автомате уже оптимизирует это выражение как положенно.
|
|
|
Записан
|
|
|
|
|