Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: О функциях классов (мысли по ходу дела)  (Прочитано 16706 раз)
0 Пользователей и 7 Гостей смотрят эту тему.
Migmile
Помогающий

ru
Offline Offline

« : 02-10-2003 08:33 » 

Для обсуждения Улыбаюсь
Иногда возникает неудержимое желание (у начинающих программистов на С++) передать куда-то вне класса адрес функции-члена этого класса и затем вызывать ее, не привязываясь к объектам этого класса.
Например:
class A
{
public:
void func(void);
};
 
A aa;
void (*ptr)(void)=aa.func;
 
ptr();  -- - без указания объекта класса
НО!!!!!
Почему компилятор каждый раз старательно (и даже с каким-то садистским удовольствием) бьет нас по рукам? Предположим, что func работает с какой-то локальной переменной v1, которая  создается в стеке, и переменной-членом класса А v2. В действительности, когда func обращается к v2 происходит обращение к *this.v2 (this->v2), где this - первый неявный параметр func. this - указатель на объект класса А - область памяти, где лежат все переменные какого-то конкретного экземпляра (объекта). Но Для Всех экземпляров функция func имеет один  и тот-же адрес, так как ее код создается компилятором только один раз. Поэтому сама функция не имеет понятия об окружающем мире, разве только через this. Если вы хотите использовать адрес функции без
привязки к объекту необходимо сгенерировать параметр this вручную - поместить некий осмысленный адрес в стек при передаче параметров перед вызовом func. Это не так уж и просто.
Теперь о поводу v1. С ней все просто. Она создается в стеке, указатель на текущее положение в котором также передается в любую функцию. Поэтому с локальными переменными в случае приведенного выше жульничества проблем не должно быть.
Записан
SlavaI
Главный специалист

ru
Offline Offline

« Ответ #1 : 02-10-2003 08:53 » 

Мы тут уже это обсуждали и не раз, вот только не могу найти где, может в старом форуме, а может пропало(был тут сбой с базой). Даже с примерами из STL, как там получают указатели на ф-ции классов.
Записан
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #2 : 02-10-2003 08:55 » 

SlavaI, это и то и не то. Человек пытается универсализовать методы, как я понял - предлагает статью - но в виде вот такого образца пока.
Если есть возможность подкорректировать конкретный пример то было бы неплохо.
Записан

А птичку нашу прошу не обижать!!!
SlavaI
Главный специалист

ru
Offline Offline

« Ответ #3 : 02-10-2003 09:01 » 

А вот я нашел, где мы обсуждали

https://forum.shelek.ru/index.php/topic,245.0.html

Надо это посмотреть, может критику навести.
Записан
Serega
Гость
« Ответ #4 : 02-10-2003 20:09 » new

STL все становится намного проще
Код:
struct Test
{
void Print()
{
cout << "Test: print from member function" << endl;
}
};

void Print(const Test& test)
{
cout << "Test: print from global function" << endl;
}

void main()
{
vector<Test> v(5);
for_each(v.begin(),v.end(),mem_fun_ref(Test::Print));
for_each(v.begin(),v.end(),Print);
}

« Последнее редактирование: 20-11-2007 17:20 от Алексей1153++ » Записан
Migmile
Помогающий

ru
Offline Offline

« Ответ #5 : 03-10-2003 06:32 » 

Спасибо за ссылку, интересное чтиво (хоть и сумбурное Улыбаюсь )
Не подскажет ли кто-нибудь, описана ли в стандарте С++ VMT или же это зависит от конкретной реализации компилятора. В VC6 - вначале класса указатель на VMT, в которой список указателей на вирт. функции.
Записан
NetRaider
Гость
« Ответ #6 : 06-10-2003 06:29 » 

Цитата

Не подскажет ли кто-нибудь, описана ли в стандарте С++ VMT или же это зависит от конкретной реализации компилятора. В VC6 - вначале класса указатель на VMT, в которой список указателей на вирт. функции.


В стандарте нет описания реализации механизма виртуальных функций(кстати помимо vtable существует еще насколько методов). Некоторую информацию по внутренностям с++ можно найти здесь http://www.codesourcery.com/cxx-abi/abi.html
Записан
Asan
Гость
« Ответ #7 : 06-10-2003 06:45 » 

Цитата: Migmile
Спасибо за ссылку, интересное чтиво (хоть и сумбурное Улыбаюсь )
Не подскажет ли кто-нибудь, описана ли в стандарте С++ VMT или же это зависит от конкретной реализации компилятора. В VC6 - вначале класса указатель на VMT, в которой список указателей на вирт. функции.


Стандарт C++ тут конечно не причем,
VMT, она сама по себе вещь не сложная - просто адреса функций.
Записан
NetRaider
Гость
« Ответ #8 : 06-10-2003 07:22 » 

Цитата

Иногда возникает неудержимое желание (у начинающих программистов на С++) передать куда-то вне класса адрес функции-члена этого класса и затем вызывать ее, не привязываясь к объектам этого класса.

 
static  :?:

void (*ptr)(void)=aa.func;

Нельзя преобразовать указатель на функцию-член класса к указателю на void.
Записан
Migmile
Помогающий

ru
Offline Offline

« Ответ #9 : 06-10-2003 14:38 » 

Цитата

Нельзя преобразовать указатель на функцию-член класса к указателю на void.

Чем С++ хорош, так это тем, что все что угодно можно преобразовывать к чему угодно Улыбаюсь  Вопрос только в том, будет-ли результат соответствовать ожидаемому!
Записан
NetRaider
Гость
« Ответ #10 : 07-10-2003 06:12 » 

Отсюда:

https://forum.shelek.ru/index.php/topic,245.0.html

Цитата
Подскажите кто может (пытаюсь перелезть на VC из Delphi),
как получить указатель на виртуальный метод класса в VC ?

Код:
class A
{
public:
virtual int a()| return 1;}
};

class B : public A
{
public:
int a()| return 2; }
};


int main()
{
B b;
A a;

int(A::*ptr)() = &A::a; // получили указатель

int c1 = (b.*ptr)(); // вызов B::a
int c2 = (a.*ptr)(); // вызов A::a


// либо так(если имеется указатель бвзового класса на производный объект)
A *p;
p = &b;
int x = (p->*static_cast<int (A::*)()>(&B::a)) ();
return 0;
}
« Последнее редактирование: 20-11-2007 17:22 от Алексей1153++ » Записан
Migmile
Помогающий

ru
Offline Offline

« Ответ #11 : 10-10-2003 08:05 » 

Интересно, что для Builder-а обман компилятора проходит - см. пример. компилятор 'честно' подставляет адрес на обект (this) в качестве первого параметра вирт. функции. Для VC это не проходит - он передает this через регистры

#include <iostream>
using namespace std;
class a
{
 public:
 int a1;
 virtual void f1(int a)
 {
  a1=a;
  cout<<a1<<" in a\n";
 }
};
class b:public a
{
 public:
 void f1(int a)
 {
  a1=a;
  cout<<a1<<" in b\n";
 }
};

b b;
typedef void (*Pf)(void *,int);
int aa,bb,cc;

int main(int argc, char* argv[])
{

 b.a1=7;
 void *pb;
 int **fptr;
 int * vptr;
 int * cptr;
 Pf pf;
 fptr=(int **)&b;
 pf=(Pf)**fptr; //  первый элемент vptr - у класса только 1 функция
 pb=(void*)&b;   // указатель на класс
 pf(pb,5);      // передадим адрес вместо this
 return 0;
}
//---------------------------------------------------------------------------
 Жаль  Жаль
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #12 : 13-04-2006 20:06 » 

(комент при переносе: )
--------------
объединить с ... (ссылка не работает.    см пост №4 сверху, от SlavaI )

?
------------
смайл (не тут, не помню где) не отображается

:twisted:



Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #13 : 13-04-2006 20:36 » 

Лёш, не надо "четвёртый сверху" - у каждого топика свой номер есть. Если ты имеешь ввиду #3, то линк дохлый. Посему - подредактируй как считаешь нужным и перенеси куда считаешь нужным. Смелее Ага
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines