Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как задать членом класса указатель на функцию? 
:(
    Опции темы
EvilsInterrupt
Дата 5.1.2013, 10:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: 2
Всего: 9



NoviceF
Забыл сказать о "лямбда". Если Вы помните, что в C++03 нужно писать так:

Код

bool ваша_кустом_функция(параметры)
{
   return элементарное действие по установке факта;
}

newIter = std::find_if( beg, end, ваша_кустом_функция );


В случае использования "лямбда", доступных в C++11, когда Вы знаете что ваша_кустом_функция очень маленькая, то Вы можете написать ее код, но без указания ее имени. Это удобно тем что 1) читающий код будет меньше скролить экран в другое место, чтобы увидеть реализацию, т.е. чтение кода будет более эффективным. 2) сокращает набор текста, а программистам же так не нравится много писать

PM MAIL WWW ICQ Jabber   Вверх
mes
Дата 5.1.2013, 13:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(EvilsInterrupt @  5.1.2013,  09:17 Найти цитируемый пост)
 1) читающий код будет меньше скролить экран в другое место, чтобы увидеть реализацию, т.е. чтение кода будет более эффективным. 

 smile 
Цитата(EvilsInterrupt @  5.1.2013,  09:17 Найти цитируемый пост)
2) сокращает набор текста, а программистам же так не нравится много писать

почти.. по кол-ву символов выходит также.. программистам не нравится выдумывать имена одноразовых функций ))

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



--------------------
PM MAIL WWW   Вверх
NoviceF
Дата 5.1.2013, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 313
Регистрация: 13.3.2012
Где: Ростов-на-Дону

Репутация: нет
Всего: 2



Код

bool ваша_кустом_функция(параметры)
{
   return элементарное действие по установке факта;
}
newIter = std::find_if( beg, end, ваша_кустом_функция );

это же синтаксис и пример использования обычной функции в алгоритме STL?

лямбду я понимаю как нечто 
Код

[&m]( int x )
    {
        //do work;   
    }

Это для случая:
Код

for_each( after.begin(), after.end(), [&m]( int x ) {//...});

спасибо Борису (borisbnsmile

конечно, возможен и вариант использования лямбды в роли предиката.

Цитата(mes @  5.1.2013,  14:55 Найти цитируемый пост)
это замыкание контекста 

вот об это не слышал, почитал вику, там как пример замыкания приводятся опять таки лямбда функции. Но в целом смысл понятен. Удобно, что лямбда может обращаться к внешним переменным, в том числе и по ссылке.
PM MAIL   Вверх
mes
Дата 5.1.2013, 17:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(NoviceF @  5.1.2013,  14:44 Найти цитируемый пост)
лямбду я понимаю как нечто 

лямбда на самом деле нечто большее )) если с замыканием она "анологична" функтору, то без контекста - обычной функции.. 
и ее легко можно использовать для адаптации сигнатуры :
Код


void f(int a, double b)
{
   std::cout << a << " " << b;
}

void call_fn (void(*fn)(double, int), double a, int b )
{
   fn(a, b);
}

int main ()
{
 //  call_fn(f, 8.6, 4);
 
 call_fn([](double a, int b){ f(b,a); }, 8.6, 4); 
 
}


http://liveworkspace.org/code/4xodmZ$0

Добавлено @ 17:05
то есть, в лямбде сильна не только ее анонимность, а таже ее конвертибельность, при отсутствии (ненужного) оверхеда..

Добавлено @ 17:10
вот еще один примерчик с лямбдами как с-функции:
Код

typedef void (*pfn)();

pfn arr[] = {
    [](){ std::cout << "H"; }
   ,[](){ std::cout << "a"; }
   ,[](){ std::cout << "l"; }
   ,[](){ std::cout << "l"; }
   ,[](){ std::cout << "o"; }      
};

int main ()
{
   for (auto f : arr) f();

}

http://liveworkspace.org/code/3tkd17$0

Это сообщение отредактировал(а) mes - 5.1.2013, 17:11


--------------------
PM MAIL WWW   Вверх
NoviceF
Дата 5.1.2013, 17:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 313
Регистрация: 13.3.2012
Где: Ростов-на-Дону

Репутация: нет
Всего: 2



Цитата(mes @  5.1.2013,  18:01 Найти цитируемый пост)
 
Код

call_fn([](double a, int b){ f(b,a); }, 8.6, 4);
 

головокружительные пируэты  smile

Добавлено @ 17:15
Цитата(mes @  5.1.2013,  18:01 Найти цитируемый пост)
Код

 (auto f : arr)
 

просветите, что за синтаксис?

отбой, нашёл в вики.

Надо всётаки когда-нибудь дочитать список "нововведений" в с++11.. где тут смайлик *слоупок*..

Это сообщение отредактировал(а) NoviceF - 5.1.2013, 17:19
PM MAIL   Вверх
mes
Дата 5.1.2013, 17:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(NoviceF @  5.1.2013,  16:12 Найти цитируемый пост)
просветите, что за синтаксис? 

c++11 ranged based for loop 
или тут

Это сообщение отредактировал(а) mes - 5.1.2013, 17:19


--------------------
PM MAIL WWW   Вверх
NoviceF
Дата 5.1.2013, 17:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 313
Регистрация: 13.3.2012
Где: Ростов-на-Дону

Репутация: нет
Всего: 2



Цитата(mes @ 5.1.2013,  18:18)
Цитата(NoviceF @  5.1.2013,  16:12 Найти цитируемый пост)
просветите, что за синтаксис? 

c++11 ranged based for loop 
или тут

Отличная вещь.. осталось только подружить qnx Momentics с gcc 4.7.. smile 
PM MAIL   Вверх
Нитонисе
Дата 9.1.2013, 10:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 917
Регистрация: 5.11.2009

Репутация: нет
Всего: 2



В развитие темы smile
Я тут попробовал набросать пример по наводке mes. Пишу в RAD Studio Builder XE, но думаю для данной задачи это не принципиально, просто код билдеровский.
Вот класс
Код

class TTestClass
{
    public:
        void SetFn(void (*fn)())
        {
            this->fn = fn;
        }
        void DoFn()
        {
            fn();
        }
    private:
        void (*fn)();
};

Вот заголовочный файл формы в билдере
Код

class TForm1 : public TForm
{
__published:    // IDE-managed Components
    TButton *Button1;
    TLabel *Label1;
    TRadioButton *RadioButton1;
    TRadioButton *RadioButton2;
    void __fastcall Button1Click(TObject *Sender);
private:    // User declarations

public:        // User declarations
    __fastcall TForm1(TComponent* Owner);
    void Fn1()
    {
        Label1->Caption = "Выполнена функция Fn1";
    };
    void Fn2()
    {
        Label1->Caption = "Выполнена функция Fn2";
    };
};

Вот применение моего тестового класса
Код

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    TTestClass *Test = new TTestClass;
    if (RadioButton1->Checked)
    {
        Test->SetFn(Fn1());
    }
    else
    {
        Test->SetFn(Fn2());
    }
    Test->DoFn();
    delete Test;
}

Ошибка компилятора
Код

[BCC32 Error] Unit1.cpp(23): E2468 Value of type void is not allowed
[BCC32 Error] Unit1.cpp(23): E2342 Type mismatch in parameter 'fn' (wanted 'void (*)()', got 'void')

Это чего он от меня хочет? smile И рабочий ли данный механизм впринципе, когда я своему классу подсовываю функции другого класса в качестве "приемных детей" smile
PM MAIL   Вверх
bsa
Дата 9.1.2013, 11:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Нитонисе, во-первых, указатель на метод класса несколько иначе записывается.
во-вторых, адрес метода класса берется тоже несколько иначе
в-третьих, а какое отношение данный вопрос имеет к обсуждаемой теме? С указателем на функцию в качестве члена класса у тебя проблем нет.
PM   Вверх
Нитонисе
Дата 9.1.2013, 12:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 917
Регистрация: 5.11.2009

Репутация: нет
Всего: 2



Цитата(bsa @  9.1.2013,  11:33 Найти цитируемый пост)
в-третьих, а какое отношение данный вопрос имеет к обсуждаемой теме? С указателем на функцию в качестве члена класса у тебя проблем нет.

Такое отношение, что я пока не разобрался как это сделать. Мне нужно в свой класс в разные моменты времени подсовывать разные функции других классов. Вот как в этом простом примере я передаю указатели на функции класса формы.
PM MAIL   Вверх
NoviceF
Дата 9.1.2013, 12:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 313
Регистрация: 13.3.2012
Где: Ростов-на-Дону

Репутация: нет
Всего: 2



Цитата(Нитонисе @  9.1.2013,  13:26 Найти цитируемый пост)
Мне нужно в свой класс в разные моменты времени подсовывать разные функции других классов.

 smile по-моему, какой-то порочный путь.. Какие действия будут выполнять эти функции? Будут ли обращаться к каким-либо приватным членам своего класса?
PM MAIL   Вверх
Нитонисе
Дата 9.1.2013, 13:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 917
Регистрация: 5.11.2009

Репутация: нет
Всего: 2



Цитата(NoviceF @  9.1.2013,  12:54 Найти цитируемый пост)
по-моему, какой-то порочный путь.. Какие действия будут выполнять эти функции? Будут ли обращаться к каким-либо приватным членам своего класса?

Да, будут. Я делаю класс контролирующий открытие/закрытие/сохранение файла. На форме есть набор компонентов, их состояние можно сохранить в файл, либо загрузить из файла. У разных программ будет разный набор этих оконных компонентов, куда будут загружаться данные. Соответственно разная будет реализация функций Load и Save. Но они будут обращаться к данным класса формы.
PM MAIL   Вверх
bsa
Дата 9.1.2013, 13:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Нитонисе, в стандарте С++ указатели на методы класса очень специфичные (я бы сказал - практически бесполезные субстанции). В Борландовской реализации есть более грамотные указатели (несут в себе не только указатель на сам код, но и на объект класса). Для их использования необходимо применять ключевое слово __closure. Поищи документацию во встроенной справке. Там все есть.
Если же тебе хочется работать со стандартными указателями на метод, то делается это так:
Код
class MyClass{
public:
   int f(int) const { return 1; }
};

int main() {
   int (MyClass::*fp)(int) const;
   fp = &MyClass::f;
   ...
   MyClass x;
   ...
   x.(*fp)(10); //вызовет x.f(10)
}


Добавлено @ 13:25
Цитата(Нитонисе @  9.1.2013,  14:17 Найти цитируемый пост)
У разных программ будет разный набор этих оконных компонентов, куда будут загружаться данные. Соответственно разная будет реализация функций Load и Save.
Ох... Если у тебя разные программы, то с разной реализацией нет проблем.
А вот если программа одна, а "формы разные", то да, возможно ты мыслишь в правильном направлении. Но опять же. Не совсем. В Билдере есть уже для этого все что нужно. назначь на onClick вызов нужного метода нужного класса и все.
PM   Вверх
Нитонисе
Дата 9.1.2013, 13:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 917
Регистрация: 5.11.2009

Репутация: нет
Всего: 2



bsa
Код

fp = &Simple::f; // что такое Simple в этой строчке?


Цитата(bsa @  9.1.2013,  13:21 Найти цитируемый пост)
В Билдере есть уже для этого все что нужно. назначь на onClick вызов нужного метода нужного класса и все.

Я заметил, что у меня от программы к программе копируется код по работе с файлом практически один в один, за исключением функций Load и Save. Поэтому и родилась идея все это привести к единому знаменателю. А какой OnClick предлагается обрабатывать - я не понял. Если имеется ввиду нажатие на кнопку открывающую/закрывающую файл - то конечно это сделать можно, но работа с файлом заключается не только в открытии и сохранении. Там еще контролируется состояние изменения, проверка корректности данных при открытии, при сохранении, вобщем есть ряд действий, которые одинаковы из программы в программу.
PM MAIL   Вверх
mes
Дата 9.1.2013, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Нитонисе, посмотрите в доке (вот опять очередная отсылка smile ) чем является OnClick. Это и будет "указатель на функцию" в терминах билдера.. Их можно использовать не только у форм, а также и у невизуальных компонентов..


--------------------
PM MAIL WWW   Вверх
Страницы: (3) Все 1 [2] 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1070 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.