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

Поиск:

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


Опытный
**


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

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



Пишу класс
Код

class TMyClass
{
  public:
    void SetFunc(void *f) {func = f;}
    void DoFunc() {f()};
  private:
    void *func;
};

Этот код конечно не работает, просто что бы пояснить чего я хочу. А хочу я иметь членом класса некую функцию func, реализация которой может быть произвольной. Ну вот например:
Код

function1() 
{
  ShowMessage("function1");
}
function2() 
{
  ShowMessage("function2");
}


TMyClass *mc = new TMyClass;
mc->SetFunc(function1);
mc->DoFunc(); // выводит сообшение "function1"
mc->SetFunc(function2);
mc->DoFunc(); // выводит сообшение "function2"


Как это сделать?
PM MAIL   Вверх
EvilsInterrupt
Дата 4.1.2013, 14:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


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

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



Нитонисе
1)
Код

    void DoFunc() {f()};

Это верно? Если оформить по красивее, то:
Код

    void DoFunc()
    {
        f()
    };


2)
Почему в setFunc присваиваете в переменную "void *func;", а в DoFunc() дергаете какую-то мифическую f() ?

3)
Может Вам изучить понятие "функтор" ? Другие названия этого термина "Объект функции". Это класс с переопределенным оператором "круглые скобки", чтобы объект этого класса вел себя как функция. Т.е. "все что выглядит как функция, ведет себя как функция = есть функция"
PM MAIL WWW ICQ Jabber   Вверх
Нитонисе
Дата 4.1.2013, 15:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



С оформлением я не заморачивался, потому как писал прямо в форме ответа. Соответственно и опечатку в DoFunc допустил. А вот по п.3 видно надо изучать матчасть.
PM MAIL   Вверх
NoviceF
Дата 4.1.2013, 16:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Нитонисе @  4.1.2013,  14:37 Найти цитируемый пост)
Как это сделать? 

что-то похожее на то, что ты хочешь, есть в паттерне "Стратегия" http://ru.wikipedia.org/wiki/%D0%A1%D1%82%...BD%D0%B8%D1%8F)

вот кусок кода оттуда
Код

int _tmain(int argc, _TCHAR* argv[])
{
        Client customClient;
        Strategy_1 str1;
        Strategy_2 str2;
        Strategy_3 str3;
 
        customClient.SetStrategy(&str1);
        customClient.UseStrategy();
        customClient.SetStrategy(&str2);
        customClient.UseStrategy();
        customClient.SetStrategy(&str3);
        customClient.UseStrategy();
 
        return 0;
}

Цитата(Нитонисе @  4.1.2013,  14:37 Найти цитируемый пост)
 А хочу я иметь членом класса некую функцию func, реализация которой может быть произвольной. 

в моём понимании произвольной может быть реализации, но интерфейс должен быть фиксированным. В случае с функцией, фиксированной должна быть сигнатура.
Ну то есть здесь
Код

class TMyClass
{
  public:
    void SetFunc(void *f) {func = f;}
    void DoFunc() {f()};
  private:
    void *func;
};

 void *func; должен быть указателем на какую-то конкретную сигнатуру, и присваивать ему мы дожны функции с такой же сигнатурой, но, если требуется, различным поведением. Хотя на практике не сталкивался, но по идее должно работать smile

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


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


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

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



Цитата(NoviceF @  4.1.2013,  15:03 Найти цитируемый пост)
 В случае с функцией, фиксированной должна быть сигнатура.

понятие функция может быть легко расширено до функционального обьекта и это расскрывает новые свободы, о чeм уже было сказано выше..
для ознакомления с подобной концепцией см.   [boost:: / (c++11)std::] function и bind..

Добавлено через 2 минуты и 16 секунд
Цитата(Нитонисе @  4.1.2013,  12:37 Найти цитируемый пост)
 А хочу я иметь членом класса некую функцию func, реализация которой может быть произвольной. 

для простой функции никаких наворотов не требуется, всe работает из коробки )


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


Executables research
***


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

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



Нитонисе
Поясни какую проблему ты решаешь? Для чего потребовался такой код? Возможно есть решение проще.
PM MAIL WWW ICQ Jabber   Вверх
mes
Дата 4.1.2013, 18:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Нитонисе @  4.1.2013,  12:37 Найти цитируемый пост)
private:
    void *func;

вот набросок :
Код

#include <iostream>

struct A { 
   
   void (*some_fn)();
   
   void do_some () {
      some_fn();
   }
}; 
void f1 () { std::cout << 1; }
void f2 () { std::cout << 2; }

int main ()
{
   A a;
   a.some_fn = f1;   
   a.do_some();
   
   a.some_fn = f2;   
   a.do_some();   
}



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


Опытный
**


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

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



 smile для понимания, пожалуйста, сделайте набросок, чего в данном примере можно добиться используя функтор, вместо указателя на функцию и почему требования к сигнатуре можно игнорировать.
PM MAIL   Вверх
EvilsInterrupt
Дата 4.1.2013, 20:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


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

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



NoviceF
По моему никнейму поищи недавнюю тему, которую я создал. В ней  про функторы достаточно много рассказано
PM MAIL WWW ICQ Jabber   Вверх
mes
Дата 4.1.2013, 23:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(NoviceF @  4.1.2013,  19:26 Найти цитируемый пост)
используя функтор, 

глянуть хотя бы на стл :
Код

 using namespace std::placeholders; 
 auto found = std::find_if(v.begin(), v.end(), 
    std::bind(std::logical_and<bool>()
              , std::bind(std::less<int>(),10, _1)
              , std::bind(std::greater<int>(),15, _1)
            ) );

http://liveworkspace.org/code/409lqK$0

Добавлено через 3 минуты и 54 секунды
если вместо 10 и 15 поставить переменные, то реализовать подобное через указатели на функции будет затруднительно..

Добавлено через 6 минут и 52 секунды
ну а с лямбдой, как дальнейшее развитии функтора, выглядит еще удобнее :
http://liveworkspace.org/code/409lqK$2

Добавлено через 9 минут и 31 секунду
 ну и с замыканием контекста : http://liveworkspace.org/code/409lqK$3

все это приведенно на скорую руку, на самом деле преимущества гораздо шире )


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


Executables research
***


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

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



mes
Я бы предпочел так оформить код:
Код

auto found = std::find_if(v.begin(), v.end(),
    [=](int i) 
    {
       return (i>min && i<max); 
    }
);


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


Опытный
**


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

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



Спасибо за примеры, но представление о функторах и лямбдах я имею smile вопрос был больше из области по данному классу.. Вывод, как я понимаю, в том, что в фиксированную сигнатуру, благодаря функторам/лямбдам, можно запихать много чего?

Это сообщение отредактировал(а) NoviceF - 4.1.2013, 23:47
PM MAIL   Вверх
EvilsInterrupt
Дата 4.1.2013, 23:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


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

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



NoviceF
Польза от использования функторов в том что это объекты! А объекты имеют состояние. То есть перед подачей объекта куда-либо ты можешь его про инициализировать, а после того как это "куда-либо" отработало ты еще можешь прочитав его состояние знать результат какой-угодно тебе.

Рекомендую книгу Джосьютиса "Стандартная библиотека C++". Сам читаю, очень опечален тем что раньше ее не прочитал (((
PM MAIL WWW ICQ Jabber   Вверх
NoviceF
Дата 5.1.2013, 00:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(EvilsInterrupt @  5.1.2013,  00:51 Найти цитируемый пост)
Польза от использования функторов в том что это объекты! А объекты имеют состояние. То есть перед подачей объекта куда-либо ты можешь его про инициализировать, а после того как это "куда-либо" отработало ты еще можешь прочитав его состояние знать результат какой-угодно тебе.

спасибо, учту.
Цитата(EvilsInterrupt @  5.1.2013,  00:51 Найти цитируемый пост)
Рекомендую книгу Джосьютиса "Стандартная библиотека C++". Сам читаю, очень опечален тем что раньше ее не прочитал ((( 

хороших книжек много и читаю я их не быстро smile но тоже возьму на вооружение.
PM MAIL   Вверх
mes
Дата 5.1.2013, 04:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(EvilsInterrupt @  4.1.2013,  22:22 Найти цитируемый пост)
Я бы предпочел так оформить код:

Цитата(mes @  4.1.2013,  22:05 Найти цитируемый пост)
все это приведенно на скорую руку,

 smile 

Цитата(NoviceF @  4.1.2013,  22:47 Найти цитируемый пост)
из области по данному классу

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

Цитата(NoviceF @  4.1.2013,  22:47 Найти цитируемый пост)
 как я понимаю, в том, что в фиксированную сигнатуру, благодаря функторам/лямбдам, можно запихать много чего?

грубо говоря, да  smile 

Цитата(EvilsInterrupt @  4.1.2013,  22:51 Найти цитируемый пост)
 А объекты имеют состояние

 smile 

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


--------------------
PM MAIL WWW   Вверх
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   Вверх
bsa
Дата 9.1.2013, 13:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Нитонисе @  9.1.2013,  14:41 Найти цитируемый пост)
что такое Simple в этой строчке?
исправил

Цитата(Нитонисе @  9.1.2013,  14:41 Найти цитируемый пост)
Я заметил, что у меня от программы к программе копируется код по работе с файлом практически один в один, за исключением функций Load и Save.
Сделай абстрактный класс, у которого функции load и save чисто виртуальные. А в каждой своей программе делай наследника, который переопределяет эти функции. Для этого наследование и существует.
PM   Вверх
Нитонисе
Дата 9.1.2013, 18:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(bsa @  9.1.2013,  13:54 Найти цитируемый пост)
Сделай абстрактный класс, у которого функции load и save чисто виртуальные. А в каждой своей программе делай наследника, который переопределяет эти функции.

Хм. Может это и хорошая идея в данном случае.
PM MAIL   Вверх
bsa
Дата 9.1.2013, 19:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Нитонисе, использование указателей на методы - это обычно всегда плохая идея. Чаще всего, они используются для реализации каких-нибудь "улучшайзеров" языка. Например, boost::bind (или std::bind), boost::function (std::function) и пр. В обычной жизни в них потребность крайне низка. И если вдруг тебе пришла в голову идея их использовать, подумай еще разик, может лучше подойдет наследование или шаблоны?
PM   Вверх
mes
Дата 9.1.2013, 20:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(bsa @  9.1.2013,  18:56 Найти цитируемый пост)
 В обычной жизни в них потребность крайне низка. 

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

Добавлено через 1 минуту и 10 секунд
Цитата(Нитонисе @  9.1.2013,  17:26 Найти цитируемый пост)
Хм. Может это и хорошая идея в данном случае. 

 smile 


--------------------
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

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


 




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


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

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