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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> переопределение функции 
V
    Опции темы
gordmiand
Дата 25.11.2010, 21:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Подскажите пож-та каким образом верно определить различную реализацию одной и той же функции в зависимости от значения внешней переменной (parametr)? Проверять значение parametr внутри функции Func1 и в зависимости от его значения выполнять те или другие операторы нежелательно, так как эта функция вызывается сотни раз и каждый раз проверять значение parametr нет смысла – оно одно и тоже, равное заданному в начале программы…
я делаю что-то типа: 
Код

#if (parametr==1)
#define Func1(x)  (2*x*x+5)

#if (parametr==2)
#define Func1(x)  (4*x+1)


будет конечно же ошибка, так как условие для  #if должно быть константным (const), но у меня-то это значение (parametr) считывается из файла в начале программы (то есть параметр  parametr переменен)…как быть?
PM MAIL   Вверх
mes
Дата 25.11.2010, 21:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(gordmiand @  25.11.2010,  20:31 Найти цитируемый пост)
 но у меня-то это значение (parametr) считывается из файла в начале программы (

язык си или с++ ?

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



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


Опытный
**


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

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



язык С++ - пишу в  Qt 4.6....
то есть только так:
 
Код

int Func1(int x, int parametr)
{  
 if (parametr==1)  return 2*x*x+5;
 else return 4*x+1;
}

что , опять же, нежелательно...
или что Вы имели ввиду? подскажите программно пож-та...
PM MAIL   Вверх
Cheloveck
Дата 25.11.2010, 21:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

Репутация: 3
Всего: 32



Используй функторы
Код

#include <iostream>

class IFunctor
{
public:
    virtual ~IFunctor() { }
    virtual int operator () (int x) = 0;
};

class CFunctorOne :
    public IFunctor
{
public:
    virtual ~CFunctorOne() { }
    
    virtual int operator () (int x)
    {
        return 2 * x * x + 5;
    }
};

class CFunctorTwo :
    public IFunctor
{
public:
    virtual ~CFunctorTwo() { }
    
    virtual int operator () (int x)
    {
        return 4 * x + 1;
    }
};

void MegaFunction(int var)
{
    IFunctor * functor = NULL;

    switch(var)
    {
    case 1:
        functor = new CFunctorOne();
        break;
    case 2:
        functor = new CFunctorTwo();
        break;
    default:
        return;
    }

    for(int i = 0; i < 5; ++i)
    {
        std::cout << (*functor)(i + 100) << " ";
    }
    std::cout << std::endl;
    delete functor;
}

int main()
{
    MegaFunction(1);
    MegaFunction(2);
    return 0;
}


Для создания функтора можно использовать паттерн Абстрактная фабрика

Это сообщение отредактировал(а) Cheloveck - 25.11.2010, 21:54


--------------------
user posted image
PM Jabber   Вверх
gordmiand
Дата 25.11.2010, 21:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Cheloveck: это явно не самый простой способ - функторы, дополнительные классы для каждой функции...надо как-то проще...гораздо проще...
PM MAIL   Вверх
Cheloveck
Дата 25.11.2010, 22:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

Репутация: 3
Всего: 32



Цитата(gordmiand @  25.11.2010,  21:54 Найти цитируемый пост)
надо как-то проще...гораздо проще... 

тогда указатели...
Код

#include <iostream>

class CProcess
{
    typedef int (CProcess::*FooType)(int x);
public:
    CProcess(int var)
    {
        switch(var)
        {
        case 1:
            m_function = &CProcess::Foo1;
            break;
        case 2:
            m_function = &CProcess::Foo2;
            break;
        default:
            m_function = &CProcess::Stub;
            break;
        }
    }

    int Run(int x)
    {
        return (this->*m_function)(x);
    }

private:
    int Foo1(int x)
    {
        return 2 * x * x + 5;
    }

    int Foo2(int x)
    {
        return 4 * x + 1;
    }

    int Stub(int)
    {
        return 0;
    }

private:
    FooType m_function;
};

void MegaFunction(int var)
{
    CProcess process(var);
    for(int i = 0; i < 5; ++i)
    {
        std::cout << process.Run(i + 100) << " ";
    }
    std::cout << std::endl;
}

int main()
{
    MegaFunction(1);
    MegaFunction(2);
    return 0;
}


Это сообщение отредактировал(а) Cheloveck - 25.11.2010, 22:13


--------------------
user posted image
PM Jabber   Вверх
gordmiand
Дата 25.11.2010, 22:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



а почему так не работает:
Код

 
  parametr = 2;


     if (parametr==1)
       #define Flag


              #ifdef Flag
                          #define Func1(x)  ( x*x+12 )
              #else   #define Func1(x)  ( (x+5)/(x-2) )

              #endif


      Edit1->Text= Func1(2);

если parametr = 1; то все работает, при parametr = 2 (например); не срабатывает   #else   #define Func1(x)  ( x ) - ошибок нет, но в эдит ничего не выводится.... почему и как это испрaвить?

Это сообщение отредактировал(а) gordmiand - 25.11.2010, 22:41
PM MAIL   Вверх
Cheloveck
Дата 25.11.2010, 22:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

Репутация: 3
Всего: 32



Это то, что препроцессор передаёт компилятору
Код

$ g++ -E test.cpp
# 1 "test.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "test.cpp"
  parametr = 2;
test.cpp:6:23: warning: extra tokens at end of #else directive
     if (parametr==1)





      Edit1->Text= ( 2*2 +12 );



Добавлено через 2 минуты и 8 секунд
Почитай про препроцессор. 
Такого
Цитата(gordmiand @  25.11.2010,  22:40 Найти цитируемый пост)
 #else   #define Func1(x)  ( (x+5)/(x-2) )

делать вообще нельзя.
Препроцессор не работает в рантайме, только при компиляции.


--------------------
user posted image
PM Jabber   Вверх
gordmiand
Дата 25.11.2010, 23:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Cheloveck: почему нельзя делать 
Код

#else   #define Func1(x)  ( (x+5)/(x-2) )
???
почему же тогда
Код

  #ifdef Flag
    #define Func1(x)  ( x*x+12 )
      #else
         #define Func1(x)  ( (x+5)/(x-2) )
  #endif

отлично и верно сработает #else...но это если РУКАМИ закомментировать #define Flag - весь вопрос и состоит в том как программно задавать/не задавать #define Flag...
в любом случае Вашими способами очень сложно...мой данный пример можно как-то подкрутить до верного?
PM MAIL   Вверх
mes
Дата 25.11.2010, 23:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Код

 int fn1 (int x) { return x+1; }
 int fn2 (int x) { return x*2; }

 int (*pfn)(int) = parameter? fn1 : fn2;

 std::cout << pfn(4);



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


Опытный
**


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

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



mes : первые 2 строки понятны - определение функций fn1 и fn2... а вот что делается в третьей строке? когда вызывается функция fn1, а когда - fn2? поясните пож-та....
PM MAIL   Вверх
mes
Дата 25.11.2010, 23:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



если параметр == true (!=0) то указатель pfn инициализируется адресом fn1, иначе  fn2;
в последний строчке идет вывод в консоль результата функции..

Добавлено @ 23:31
Цитата(mes @  25.11.2010,  22:15 Найти цитируемый пост)
int (*pfn)(int) = parameter? fn1 : fn2;

можно переписать так
Код

int (*pfn)(int);
if (parameter) pfn = fn1; else pfn = fn2;


Это сообщение отредактировал(а) mes - 25.11.2010, 23:31


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


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

Репутация: 3
Всего: 32



gordmiand, способ mesа такой же, как мой последний, только требует глобальной переменной. Объекты же сами хранят своё состояние, а ведь именно это вам и надо. Если это для вас сложно, может не стоит писать на C++?

Цитата(gordmiand @  25.11.2010,  23:07 Найти цитируемый пост)
Cheloveck: почему нельзя делать 
Код

#else   #define Func1(x)  ( (x+5)/(x-2) )

Потому, что директивы препроцессора должны начинаться с символа #, и их (директив) не должно быть более одного на строку.

Это сообщение отредактировал(а) Cheloveck - 26.11.2010, 10:22


--------------------
user posted image
PM Jabber   Вверх
mes
Дата 26.11.2010, 10:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Cheloveck @  26.11.2010,  09:18 Найти цитируемый пост)
только требует глобальной переменной. 

 smile  smile 


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


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

Репутация: 3
Всего: 32



Цитата(mes @  26.11.2010,  10:47 Найти цитируемый пост)
 smile  smile 


Цитата(mes @  25.11.2010,  23:15 Найти цитируемый пост)
int (*pfn)(int) = parameter? fn1 : fn2;

Это либо то, что ТС хочет избежать, либо глобальная переменная, либо дополнительный параметр.


--------------------
user posted image
PM Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.0662 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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