Что такое "объект sentry" в C++?

Я ответ. этой вопрос и Potatoswatter ответил как

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

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

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

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

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

3 ответов


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

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

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

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

  • блоки: деструктор для объекта "Stack-allocated" вызывается в конце блока

    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 может быть называется "сторожевой объект". Они "часовые", потому что они гарантируют, что эти неуловимые деструкторы объектов не пропущены, даже если что-то выдает исключение (поэтому они похожи на стражей блока/класса).

больше примеров объектов sentry находятся в этом RAII вопрос.


вы можете видеть отношение к аспектно-ориентированному программированию; эти объекты являются чем-то вроде "аспектов" с точками отсечения "в начале / конце заключительного блока", " в строительство/разрушение, содержащих объекты" и т. д. Но эти "аспекты"!--48-->обязательно присутствуют в коде они aspectate. Таким образом, они менее "aspective" по сравнению с оригиналом call/return функциональность; вместо этого объект sentry должен быть вставлен в каждую функцию класса:

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

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

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

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

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


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