class base
{
public:
int i;
void fn();
base();
};
base::base()
{
cout<<"In base";
}
void base::fn()
{
cout<<"Super";
}
int main(int argc, char* argv[])
{
base *f;
f=NULL;
f->fn();//все работает
f->i=5;//ошибка
getch();
return 0;
}
Народ, помогите разобраться.
В примере выше я наглядно показал, как можно обратиться к функции не создавая объект класса. но почему так?
Ведь обращение к переменной i вызовет ошибку и это абсолютно верно, а к функции — нет.
Исправлена подсветка синтаксиса. -- ПК.
Здравствуйте, Max_pv, Вы писали:
M_>Народ, помогите разобраться.
M_>В примере выше я наглядно показал, как можно обратиться к функции не создавая объект класса. но почему так?
M_>Ведь обращение к переменной i вызовет ошибку и это абсолютно верно, а к функции — нет.
Если сделать функцию виртуальной или обратится из нее к переменным объекта то тоже словишь ошибку. В данном случае нет ошибки только потому что в функции не используется this.
... << RSDN@Home 1.1 alpha 1 >>
Здравствуйте, Max_pv, Вы писали:
M_>В примере выше я наглядно показал, как можно обратиться к функции не создавая объект класса. но почему так?
M_>Ведь обращение к переменной i вызовет ошибку и это абсолютно верно, а к функции — нет.
Всё просто. f->fn(); вызывает функцию в которую первым параметром неявно впихивают указатель f(т.е. в твоем случае NULL). Если ты в теле функции напишешь i = 5; то тем самым ты неявно пишешь f->i = 5 поэтому если f — невалидный(как в твоём примере), то прога рухнет, а если ты не будешь обращаться к переменным класса, то всё пройдёт на ура.
Здравствуйте, Max_pv, Вы писали:
M_>class base
M_>{
M_>public:
M_> int i;
M_> void fn();
M_> base();
M_>};
M_>base::base()
M_>{
M_> cout<<"In base";
M_>}
M_>void base::fn()
M_>{
M_> cout<<"Super";
M_>}
M_>int main(int argc, char* argv[])
M_>{
M_> base *f;
M_> f=NULL;
f->>fn();//все работает
f->>i=5;//ошибка
M_> getch();
M_> return 0;
M_>}
M_>Народ, помогите разобраться.
M_>В примере выше я наглядно показал, как можно обратиться к функции не создавая объект класса. но почему так?
Ничего ты в этом примере наглядно не показал. Попытка обращения к нестатическому члену класса через нулевой указатель приводит в языке С++ к неопределенному поведению. Точка. А что там у тебя случайно получилось никакой роли не играет. С точки зрения языка С++ твой код нелегален и, поэтому, ничего не демонстрирует.
M_>Ведь обращение к переменной i вызовет ошибку и это абсолютно верно, а к функции — нет.
Обращение к нестатическому полю класса приводит к неопределенному поведению, а не "вызывает ошибку". То же самое происходит и при обращении к нестатическому методу класса. А получится ли при этом "ошибка", или покажется, что все нормально стработало — это уже дело десятое.
Здравствуйте, Max_pv, Вы писали:
f->>fn();//все работает
f->>i=5;//ошибка
Все дело в механизме реализации классов и вызовах методов...
Так уж случилось, что при вызове метода указатель на класс не используется (т.к. код метода лежит в заранее определенном при компиляции месте, с виртуальными методами отдельный случай), но он неявно передается и виден в методе как this, и обращение к переменым данного класса из метода происходит тоже неявно с использованием this ( например i+=1; в методе тоже самое, что this->i+=1), отсюда выходит, что если бы ты обратился к переменной, то скорее всего возникла бы ошибка (в нашем случае она явно возникнет, т.к. указатель на NULL)
есле методы уже созданы при компиляции и их адрес известен, то с переменными класса все по другому, они находятся непосредственно в экземпляре класса, и для доступа к ним используется (явно или нет) адрес экземпляра класса (вданном случае адре содержит переменная f, а явным доступом к переменной является f->i; )
т.е.:
f->fn(); // функция вызывается и неверный адрес передается в качестве неявного аргумента (this)
f->i=5; // используется неверный адрес при доступе к переменной класса
... << RSDN@Home 1.1 beta 1 >>