C ++ - вопрос основной функции - PullRequest
0 голосов
/ 01 августа 2010

Можно ли вызвать функцию только один раз?

Предположим, у меня есть класс

struct A {

   void MainRoutine(Params) {
      // Want to call other routine only once
   }

   void OtherRoutine(Params) {
      // Do something that should be done only once and
      // what depends on the params
   }
};   

Я хочу вызвать OtherRoutine только один раз в MainRoutine (я предполагаю, что MainRoutine будет вызываться N раз. Я не могу вызвать OtherRoutine из конструктора, потому что он принимает Params который может быть недоступен во время создания объекта.

В основном я хочу сделать что-то вроде

static bool called = false;
if (!called) {
   OtherRoutine(Params);
   called = true;
}

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

Может быть, что-то, используя boost::function или какую-то часть boost, о которой я не знаю? :)

Спасибо

Ответы [ 5 ]

3 голосов
/ 01 августа 2010

Взгляните на механизм единовременной инициализации Boost Thread

2 голосов
/ 01 августа 2010

Этого можно добиться с помощью boost :: function и bind.Предполагая, что вы хотите, чтобы OtherRoutine вызывался только один раз для объекта,

struct A {
    A() {
        Routine = boost::bind(&A::OtherRoutine, this); 
    }

    boost::function<void()> Routine;

private:
    void MainRoutine() {
        // Do stuff that should occur on every call
    }

    void OtherRoutine() {
        Routine = boost::bind(&A::MainRoutine, this);
        // Do stuff that should only occur once
        MainRoutine();
    }
};

A foo;
foo.Routine(); // OtherRoutine is called
foo.Routine(); // Now all subsequent calls will go to MainRoutine
foo.Routine();

Я бы предложил сделать то, что говорили другие люди.Хотя это может выглядеть «чище», это слишком сложно по сравнению с альтернативами.

2 голосов
/ 01 августа 2010

Вы уже точно на правильном пути. Вы должны поместить вашу статическую переменную 'named' в вашу структуру ... ahem: вместо этого вы должны сделать ее классом, сделать ее приватной и убедиться, что состояние статической переменной запрашивается внутри OtherRoutine. Вы не должны делать это сложнее, чем должно быть . Использование boost или чего-либо еще для столь простого механизма - это просто излишество.

2 голосов
/ 01 августа 2010

Вы также можете поместить логику "только один раз в вызове", которую вы уже обрисовали, в OtherRoutine, заставляя ее вернуться рано, если она уже была выполнена ранее.так же.Стилистически это может быть лучше.

0 голосов
/ 01 августа 2010

Еще один способ, которым грани «симпатичного» - это иметь статический объект и вызывать вашу функцию из его конструктора. Что-то вроде ...

   struct OneShotOtherRoutine
   {
      OneShotOtherRoutine(A a, Params params)
      {
         a.OtherRoutine(params);
      }
   };

   struct A
   {
      friend struct OneShotOtherRoutine;
      public:
         void MainRoutine(Params params)
         {
              static OneShotOtherRoutine(params);
              // Main Routine code
         }
      private:
         void OtherRoutine(Params params)
         {
           // Other routine code
         }
  };

Вам придется разделить вещи так, чтобы каждая реализация могла видеть объявление другой структуры, но это могло бы делать то, что вы хотите, при условии, что допустимо, что OtherRoutine вызывается при инициализации статики.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...