【问题标题】:What is "sentry object" in C++?什么是 C++ 中的“哨兵对象”?
【发布时间】:2011-02-11 01:29:08
【问题描述】:

answered这个questionPotatoswatteranswered也是

现代 C++ 等价物是 哨兵对象:在 函数的开头,及其 实现 call() 的构造函数,以及 返回(或异常退出)时,其 析构函数实现

我不熟悉在 C++ 中使用哨兵对象。 我认为它们仅限于输入和输出流。

有人可以向我解释一下 C++ 哨兵对象以及如何将它们用作类中一个或多个方法的环绕拦截器吗?

即如何做到这一点?

Sentry 对象非常相似 确实。一方面他们需要 显式实例化(并且是 通过了这个)但另一方面你 可以添加到他们,以便他们检查不 只有类的不变量,但 一些前置/后置条件 手头的功能。

【问题讨论】:

  • 除了这个问题很可能是一个骗子,请不要在询问通用 C++ 问题时使用任何与 Visual Studio 相关的标签来标记您的问题。
  • @Pavel 我搜了没找到
  • @Pavel 抱歉,这是我的第一个问题

标签: c++ idioms


【解决方案1】:

Sentry 对象是一种模式,但我不确定以下哪个(可能全部)。

C++ 程序通常在某个对象(可能是用户定义的类)被销毁时(即调用其析构函数时)严重依赖知识。对于具有垃圾收集功能的语言,情况并非如此。

此技术用于,例如,采用“资源获取即初始化”范式:在调用对象构造函数时获取资源,编译器会自动调用其析构函数以在正常和异常(异常)情况下释放资源(检查this question)。

您可以利用建造/销毁时间知识的常见地方是

  • :在块的末尾调用“堆栈分配”对象的析构函数

    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 question


您可以看到与面向方面编程的关系;这些对象类似于“方面”,具有“在封闭块的开始/结束处”、“在包含对象的构造/销毁时”等的切点。但是这些“方面”必须出现在他们方面的代码。因此,与原始的 call/return 功能相比,它们的“外观”更少;相反,应该在类的每个函数中插入一个哨兵对象:

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

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

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

【讨论】:

  • @Romian,没问题,我只是在尽力拖延实际工作>_
  • 我们不都知道吗...:)
【解决方案2】:

与 AOP 的不同之处在于它必须合作通过将哨兵明确地放置在函数体或类定义中的某个位置来完成。

如果不修改目标函数或类,您将无法捕获调用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-21
    • 2017-01-11
    • 2014-10-11
    • 2014-09-23
    • 2011-01-11
    • 1970-01-01
    • 2015-05-18
    相关资源
    最近更新 更多