указатель на функцию-элемент класса...
, или адрес функции-элемента класса. не получается.
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.116] |
|
|
указатель на функцию-элемент класса...
, или адрес функции-элемента класса. не получается.
|
Сообщ.
#1
,
|
|
|
|
Подскажите, пожалуйста, как разобраться с проблемкой в программе:
Решил попробовать использовать классы С++ и наткнулся вот на какую ситуацию. у меня есть два класса. в одном описан элемент-функция. во втором - элемент-указатель на функцию. Хочется присвоить указателю адрес этой функции-элемента, а не получается. Вот если указателю подсунуть "просто функцию", вне класса - всё нормально. Для иллюстрации набросал вот такой примерчик: ![]() ![]() //-------------------- class class_a { public: char (*fptr)(char); }; //-------------------- class class_b { public: char f(char); }; //------------------- char class_b::f(char) { return '!'; } //------------------- char f2(char) { return '~'; } //------------------- int main() { class_a a; class_b b; a.fptr = f2; // a.fptr = b.f; // Error[Pe300]: a pointer to a bound function may only be used to call the //function // a.fptr = class_b::f;// Error[Pe513]: a value of type "char (__code class_b::*)(char)" cannot be //assigned to an entity of type "char (*)(char)" return 0; } вот f2, функция "сама по себе", нормально присваивается. а на закомментированные строчки компилятор ругается. как правильно надо? Просьба гнилыми помидорами не забрасывать .ЗЫ. компилятор используется IAR 3.21, но стандарты языка везде одинаковы... |
|
Сообщ.
#2
,
|
|
|
|
Предположение - сделать метод в классе B, который будет возвращать указатель на функцию class_b::f, и вызывать этот метод из класса class_a?
|
|
Сообщ.
#3
,
|
|
|
|
Цитата //nikson @ // a.fptr = b.f; // Error Или делай свою функцию в class_b статической, или используй тип (class_b::*)(char) в качестве указателя на функцию. |
|
Сообщ.
#4
,
|
|
|
|
Цитата //nikson @ вот f2, функция "сама по себе", нормально присваивается. а на закомментированные строчки компилятор ругается. как правильно надо? Просьба гнилыми помидорами не забрасывать Все дело в том, что указатель на функцию-член - далеко не тоже самое, что указатель на свободную функцию. Вот компилятор и ругается. Я бы предложил сделать так: ![]() ![]() //-------------------- class class_a { public: boost::function<char (char)> fptr; }; //-------------------- class class_b { public: char f(char); }; //... //... int main() { class_a a; class_b b; a.fptr = boost::bind(&b::f, &b, _1); a.fptr('A'); return 0; } |
|
Сообщ.
#5
,
|
|
|
|
![]() ![]() class MyClass{ typedef long ( MyClass::* FPTR )( int ); public: long func( int a ){ return ++a; } long func( int a, char b ){ return a += b; } void anyfunc( FPTR function, int a ){ a = (this->*function)( a ); } void runfunc(){ anyfunc( &MyClass::func, 5 ); } }; |
|
Сообщ.
#6
,
|
|
|
|
![]() ![]() //-------------------- class class_b { public: char f(char); }; //------------------- char class_b::f(char) { return '!'; } class class_a { public: char (class_b::*fptr)(char); }; //------------------- int main() { class_a a; class_b b; a.fptr = &class_b::f; (b.*a.fptr)('a'); return 0; } |
|
Сообщ.
#7
,
|
|
|
|
Большое спасибо всем ответившим!
Несколько комментариев, зачем такое понадобилось. Программа предназначена для микроконтроллера, у прибора будет ЖКИ, и необходимо обеспечить графический интерфейс с пользователем. Для этого решил сделать набор простеньких классов а-ля Билдер - кнопочки, надписи итд. Получается, в программе есть *чисто программные* блоки (те самые графические элементы), а есть аппаратно-зависимые (работа с памятью, клавиатурой итд итп). Логично было бы их разделить. В самом деле, например, классу _надпись_ при отрисовке совершенно не надо знать, откуда и каким образом берётся массив байт с изображением (в разных устройствах может же быть по-разному) - ему просто подавай функцию, которая на заданный символ вернёт указатель на буфер (а сама реализует связь с памятью, обмен данными итд). Вот такую функцию я сделал в классе _микросхема_памяти_, образно говоря. При попытке подсунуть её классу _надпись_ и возник вопрос ![]() Поэтому наиболее подходящий вариант от Flex Ferrum с использованием boost:: - почитал доки - вроде бы в самый раз будет. Если удастся это использовать и код особо не увеличится в размерах - будет просто супер! В принципе, можно попробовать сделать статическую функцию, но как это повлияет на работу - надо будет ещё подумать. Ну, а использовать внутри класса с указателем хоть какое-нибудь упоминание о другом классе (напр, в типе указателя) не хотелось бы - нарушается принцип независмости, из-за которого всё это и было затеяно. ЗЫ. тему не закрываю, а вдруг с boost сам не разберусь, тогда ещё поспрашиваю |
|
Сообщ.
#8
,
|
|
|
|
boost в мелкоконтроллере - довольно смело.
|
|
Сообщ.
#9
,
|
|
|
|
Цитата trainer @ boost в мелкоконтроллере - довольно смело. Я думаю, от компилятора зависит. bind/function разворачиваются оптимизатором очень даже неплохо. |
|
Сообщ.
#10
,
|
|
|
|
Там(в function) исключения вроде используются, а в них - std::string.
|
|
Сообщ.
#11
,
|
|
|
|
Цитата //nikson @ В принципе, можно попробовать сделать статическую функцию, но как это повлияет на работу - надо будет ещё подумать. Дык всё зависит от того, что ты хочешь сделать. Если твоя функция class_b::f работает с данными уже существующего объекта типа class_b, то тогда её не надо делать статической. Если же тебе нужен просто аналог глобальной функции с правом доступа к закрытым членам объектов типа class_b, используемых где-то внутри этой функции, либо ты просто хочешь выразить принадлежность этой функции к данном классу (хотя по сути её можно было бы сделать глобальной), то тогда следует использовать статическую функцию. Наконец, может ты вообще захотел сгруппировать глобальные функции в некую именованную совокупность, но тогда для этого лучше подходит пространство имён, а не класс. P.S. С бустом с таким знанием языка работать не советую :-) |
|
Сообщ.
#12
,
|
|
|
|
Цитата //nikson, 19.07.2006, 2:37:59, 1182897 ЗЫ. компилятор используется IAR 3.21, но стандарты языка везде одинаковы... под какой контроллер? при описание класса IAR сожрал много памяти (работали с ATMeag8) |
|
Сообщ.
#13
,
|
|
|
|
Цитата под какой контроллер? msp430f149. на борту 60кб - пока ещё место есть |
|
Сообщ.
#14
,
|
|
|
|
Ой... а чем для контроллера Си не устаривает? ИМХО для таких целей Си куда более пригоден, чем Си++.
|