но это не компилируется, я что-то слышал о том,
что передаваемый this — это неявный указатель.
Почему адрес свойства объекта я могу получить
во время исполнения, а адрес метода нет?
может есть какие либо обходные методы решения?
спасибо, Роман.
Re: как получить адрес метода объекта внутри другого метода
R>но это не компилируется, я что-то слышал о том, R>что передаваемый this — это неявный указатель. R>Почему адрес свойства объекта я могу получить R>во время исполнения, а адрес метода нет?
R>может есть какие либо обходные методы решения?
R>спасибо, Роман.
Re: как получить адрес метода объекта внутри другого метода
Здравствуйте, Сергей Зизев, Вы писали: СЗ>Тип указателя ptr не соответствует типу присваемого ему значения. СЗ>Тип функции action void (abc::*ptr_to_action_function)()
дело не в этом, вот другой, консольный пример,
всё, что написано в функции main работает,
а в классе ptr=&data; работает, а ptr=&action; — нет
я понимаю всю опасность получения подобных адресов,
но всё-таки не понятно, почему адрес свойства можно получить
как и для глобальной переменной, а адрес функции класса нет?
спасибо, Роман.
Исправлена подсветка синтаксиса. -- ПК.
class abc {
public:
int data;
void action () { }
void func () {
void *ptr;
ptr=&data;
ptr=&action; //не работает
}
};
int glob_data;
void glob_action () { }
void main () {
void *ptr;
ptr = &glob_data;
ptr = &glob_action;
}
Re[3]: как получить адрес метода объекта внутри другого мето
Здравствуйте, romamoramento, Вы писали:
R>но всё-таки не понятно, почему адрес свойства можно получить R>как и для глобальной переменной, а адрес функции класса нет?
А зачем это надо?
... << RSDN@Home 1.0 beta 4 >>
Re[3]: как получить адрес метода объекта внутри другого мето
Правильный синтаксис &abc::action; результат этой операции — так называемый указатель на член. Присвоить его переменной типа void* нельзя, хотя бы потому что sizeof(&abc::action) в общем случае не равен sizeof(void*). Читать об указателях на члены.
R>
Здравствуйте, romamoramento, Вы писали:
R>но всё-таки не понятно, почему адрес свойства можно получить R>как и для глобальной переменной, а адрес функции класса нет?
Переменная класса содержит только его переменные-члены.
Вызов функции класса происходит почти как вызов обыкновенной функции, и компилятор добавляет первый, "невидимый" для нас параметр CClass* this, с помощью которого можно обращаться к полям данных нужной нам переменной типа CClass.
Поэтому мы и не можем получить указатель на функцию-член класса стандартными способами.
Re[3]: как получить адрес метода объекта внутри другого мето
Здравствуйте, romamoramento, Вы писали:
R>Здравствуйте, Сергей Зизев, Вы писали: СЗ>>Тип указателя ptr не соответствует типу присваемого ему значения. СЗ>>Тип функции action void (abc::*ptr_to_action_function)()
R>дело не в этом, вот другой, консольный пример, R>всё, что написано в функции main работает, R>а в классе ptr=&data; работает, а ptr=&action; — нет R>я понимаю всю опасность получения подобных адресов, R>но всё-таки не понятно, почему адрес свойства можно получить R>как и для глобальной переменной, а адрес функции класса нет? R>спасибо, Роман.
R>
R>
class abc {
R>public:
R> int data;
R> void action () { }
R> void func () {
R> void *ptr;
R> ptr=&data;
R> ptr=&abc::action; //Такие преобразования вообще недопустимы, тем более,
//что action не является статическим членом класса. Если ты хочешь все таки работать с методом косвенно, то смотри мой первый ответ
R> }
R> };
R>int glob_data;
R>void glob_action () { }
R>int main () {
R>void *ptr;
R>ptr = &glob_data;
Это преобразование тоже неверно, т.к. у тебя нет никакой гарантии, что размер адреса функции будет совпадать с размером указателя
R>ptr = &glob_action;
R>}
Re[3]: как получить адрес метода объекта внутри другого мето
Здравствуйте, romamoramento, Вы писали:
СЗ>>Тип указателя ptr не соответствует типу присваемого ему значения. СЗ>>Тип функции action void (abc::*ptr_to_action_function)()
R>дело не в этом, вот другой, консольный пример, R>всё, что написано в функции main работает, R>а в классе ptr=&data; работает, а ptr=&action; — нет R>я понимаю всю опасность получения подобных адресов, R>но всё-таки не понятно, почему адрес свойства можно получить R>как и для глобальной переменной, а адрес функции класса нет?
Адрес поля объекта можно тоже получить двумя способами. Если в классе 'A' есть поле 'f' типа 'int', то выражение '&f' на территории какого-нибудь метода класса 'A' или выражение '&(A::f)' (скобки важны) будет давать "обычный" указатель на это поле — типа 'int*'. Это указатель можно привести к типу 'void*'. А вот выражение '&A::f' будет давать указатель типа "указатель на член класса" — тип 'int A::*'. Это указатель нельзя привести к типу 'void*'.
Это все отностится к полям классов. Что касается нестатических методов классов, то указатели на них можно получить только одним способом — как указатели типа "указатель на член класса". Если в классе 'A' есть метод 'int m(double)', то выражение '&A::m' будет давать указатель типа 'int (A::*)(double)'. Этот указатель не может быть приведен к типу 'void*'.
То, что написано в твоем изначальном коде — полная ерунда. Получить указатель на нестатический метод класса можно только при помощи явного применения оператора '&' и с указанием полностью квалифицированного имени метода '&<имя класса>::<имя метода>'.
P.S. 'romamoramento' — это что, поклонник Mylene Farmer?
Best regards,
Андрей Тарасевич
Re[3]: как получить адрес метода объекта внутри другого мето
привет,
спасибо всем кто помог разобраться, кстати этот консольный пример
компилируется на билдере и вижуал, и адрес _метода класса_ можно
тоже получить как void*, указав метод как static.
лично я понимаю void* как указатель на что-то — т.е. адрес,
а он должен быть у любого поля и функции.
Ещё раз спасибо, миленофан Роман.
Re[4]: как получить адрес метода объекта внутри другого мето
Павел, а почему main должна быть int? Это стандарт? Я вроде все время void использую, но это под VC.
Re[4]: как получить адрес метода объекта внутри другого мето
От:
Аноним
Дата:
22.01.03 07:41
Оценка:
Здравствуйте, romamoramento, Вы писали:
R>лично я понимаю void* как указатель на что-то — т.е. адрес, R>а он должен быть у любого поля и функции.
void* — это нетипизированный указатель на данные.
Смешивать его с указателями на код нельзя не только по смыслу, но и в силу того, что существуют архитектуры, где адреса данных имеют иную природу, нежели адреса кода (т. е. память для данных отдельна и отлична от памяти для кода).
Re[5]: как получить адрес метода объекта внутри другого мето
Здравствуйте, Gadsky, Вы писали:
G>Павел, а почему main должна быть int? Это стандарт? Я вроде все время void использую, но это под VC.
Прошу прощения, что вмешиваюсь ,но:
C++ Standard, 3.6.1/2
An implementation shall not predefine the main function. This function shall not be overloaded. It shall
have a return type of type int, but otherwise its type is implementationdefined.
All implementations
shall allow both of the following definitions of main:
int main() { /* ... */ }
and
int main(int argc, char* argv[]) { /* ... */ }
Re[5]: как получить адрес метода объекта внутри другого мето
Здравствуйте, romamoramento, Вы писали:
R>спасибо всем кто помог разобраться, кстати этот консольный пример R>компилируется на билдере и вижуал, и адрес _метода класса_ можно R>тоже получить как void*, указав метод как static. R>лично я понимаю void* как указатель на что-то — т.е. адрес, R>а он должен быть у любого поля и функции.
Адрес и указатель — разные вещи. Указатель в общем случае — это больше чем адрес. В С++ существует несколько категорий указателей:
1. указатели на "самостоятельные" данные (включая "обычные" указатели на поля классов)
struct A
{
int i;
void foo();
static int bar(double);
};
A a;
int i;
void foo();
int* p = &i;
int* q = &a.i;
2. указатели на "самостоятельные" функции (включая статические методы классов)
void (*p)() = &foo;
int (*q)(double) = &A::bar;
3. указатели на нестатические методы классов (указатели типа "указатель на член класса")
void (A::*p)() = &A::foo;
4. указатели на нестатические поля классов (указатели типа "указатель на член класса")
int A::*p = &A::i;
Указатели в этих группах в С++ имеют разную природу и приведения типов между группами в С++ невозможно. Что там тебе позволяет делать компилятор никакого значения не имеет — все равно легальным С++ это не будет и, в конце концов, добром не кончится.
В твоем случае указатель типа 'void*' является указателем первой группы. Укзатель на статический метод — указатель второй группы. Приведение типа между этими типами невозможно.