Что такое «часовой объект» в C ++? - PullRequest
14 голосов
/ 22 апреля 2010

Я ответил на этот вопрос и Картофельная вода ответил тоже как

Современный эквивалент C ++ будет часовой объект: построить его на начало функции, с ее конструктор, реализующий call (), и по возвращении (или ненормальный выход), его деструктор реализует

Я не знаком с использованием сторожевых объектов в C ++. Я думал, что они были ограничены входными и выходными потоками.

Может ли кто-нибудь объяснить мне о сторожевых объектах C ++, а также о том, как использовать их в качестве перехватчика для одного или нескольких методов в классе?

т.е. Как это сделать?

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

Ответы [ 3 ]

16 голосов
/ 22 апреля 2010

Объект Sentry является шаблоном, но я не уверен, какой из приведенных ниже (возможно, всех).

Программы на C ++ часто в значительной степени полагаются на знания, когда именно объект (возможно, пользовательского класса)) уничтожается, т.е. когда вызывается его деструктор.Это не относится к языкам с сборкой мусора.

Этот метод используется, например, для охвата парадигмы «Приобретение ресурсов является инициализацией»: вы получаете ресурсы, когда вызывается конструктор объекта, и компилятор автоматически вызываетего деструктор для освобождения ресурсов как в нормальных, так и в ненормальных (исключительных) ситуациях (отметьте этот вопрос ).

Общие места, где вы можете использовать знание сроков строительства / разрушения:

  • Blocks : деструктор для "выделенного стека" объекта вызывается в конце блока

    void function()
    {  Class foo = Object(resource);
       other_operations();
    }  // destructor for foo is called here
    
  • Вызовы функций : «выделение стека» также происходит при вызове функции

    void function()
    {  another_function ( Class(resource)  );
       // destructor for the unnamed object is called
       // after another_function() returns (or throws)
       other_operations();
    }
    
  • Строительство / Уничтожение содержащего объекта :

    class Foo
    {  Class sentry;
       public: Foo()
       { // Constructor for sentry is called here
          something();
       }        
       public: ~Foo()
       {
          something();
       }  // destructor for sentry is called here
    };
    

В STL есть класс с именем sentry (точнее, istream::sentry), который реализует третий шаблон из описанных выше.Поэтому я думаю, что это то, что некоторые программисты называют «сторожевым объектом».

Но на самом деле любой из вышеперечисленных объектов класса Class можно назвать «сторожевым объектом».Они "сторожевые", потому что они гарантируют, что эти неуловимые деструкторы объектов не будут пропущены, даже если что-то выдает исключение (таким образом, они подобны хранителям своего рода / класса).

В этом примере приведены еще несколько примеров сторожевых объектов Вопрос RAII .


Вы можете увидеть отношение к аспектно-ориентированному программированию;эти объекты являются чем-то вроде «аспектов», с точками отсечения «в начале / конце вмещающего блока», «при строительстве / разрушении вмещающего объекта» и т. д. Но эти «аспекты» должны присутствовать вкод они аспектируют.Таким образом, они менее «перспективны» по сравнению с оригинальной call/return функциональностью;вместо этого часовой объект должен быть вставлен в каждую функцию класса:

class X{
  struct Sentry {
     Sentry() { /* call() */}
    ~Sentry() { /* return() */};
  };

  void member_function()
  { Sentry();
    /* operations */
  }

  void another_member_function()
  { Sentry();
    /* operations */
  }
};
3 голосов
/ 22 апреля 2010

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

Вы не можете перехватывать вызовы без изменения целевой функции или класса.

2 голосов
/ 22 апреля 2010

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

...