什么是“哨兵对象”在C ++? [英] What is "sentry object" in C++?

查看:405
本文介绍了什么是“哨兵对象”在C ++?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

回答问题 Potatoswatter 回答



< blockquote>

现代的C ++等价物将是一个
sentry对象:在
函数的开始处构造它,其
构造函数实现call(),
当返回(或异常退出),它的
析构函数实现


我不熟悉使用sentry对象C ++。
我认为他们只限于输入和输出流。



有人可以向我解释C ++ sentry对象以及如何使用它们作为一个拦截器对于类中的一个或多个方法?



ie如何做到这一点?


Sentry对象非常相似
。一方面,它们需要
显式实例化(并且
传递这个),但另一方面,
可以添加到他们,以便他们检查不是
只有不变量但是
有一些前/后条件为
函数在手。



解决方案

Sentry对象是一个模式,但我不知道下面哪一个(也许全部)。



C ++程序经常严重依赖知识一个对象(可能是用户定义的类)被销毁,即当它的析构函数被调用时。



这种技术用于例如拥抱资源获取是初始化范例:当一个对象构造函数被调用,并且编译器自动调用它的析构函数来释放正常和异常(异常)情况下的资源(检查

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




  • :stack-allocated对象的析构函数在block

      void function()
    {Class foo = Object(resource);
    other_operations();
    } //这里调用foo的析构函数

  • 函数调用:当您调用函数时也会发生stack-allocation。

      another_function(Class(resource)); 
    //未命名对象的析构函数称为
    //在another_function()返回(或throws)之后
    other_operations();
    }


  • 包含对象的构造/销毁

      class Foo 
    {Class sentry;
    public:Foo()
    {//哨兵的构造函数在这里调用
    something();
    }
    public:〜Foo()
    {
    something();
    } //这里调用sentry的析构函数为
    };




在STL中有一个类 sentry (更确切地说, istream :: sentry ),它实现了上述第三种模式。所以我认为这是一些程序员称为sentry对象。



但事实上任何上述对象 Class 可以称为sentry对象。他们是哨兵,因为他们确保这些难以捉摸的对象析构函数不会错过,即使某些东西抛出异常(所以他们像块/类的监护人,各种)。



更多sentry对象的例子在 RAII问题






定向编程;这些对象是类似方面的东西,具有在封闭块的开始/结束处,在构造/破坏包含对象等处的切点。但是这些方面必须他们的代码。因此,与原来的 call / return 功能相比,它们不那么方面相反,应该在类的每个函数中插入一个sentry对象:

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

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

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


I answered this question, and Potatoswatter answered too as

The modern C++ equivalent would be a sentry object: construct it at the beginning of a function, with its constructor implementing call(), and upon return (or abnormal exit), its destructor implements

I am not familiar with using sentry objects in C++. I thought they were limited to input and output streams.

Could somebody explain to me about C++ sentry objects as well as how to use them as an around interceptor for one or more methods in a class ?

i.e. How to do this ?

Sentry objects are very similar indeed. On the one hand they require explicit instantiation (and being passed this) but on the other hand you can add to them so that they check not only the invariants of the class but some pre/post conditions for the function at hand.

解决方案

Sentry object is a pattern, but I'm not sure which one of those below (maybe all).

C++ programs often heavily rely on knowledge when exactly an object (possibly of a user-defined class) is destroyed, i.e. when its destructor is called. This is not the case for languages with garbage collection.

This technique is used, for example, to embrace "Resource Acquisition Is Initialization" paradigm: you acquire resources when an object constructor is called, and the compiler automatically calls its destructor to free resources in both normal and abnormal (exceptional) situations (check this question).

Common places where you can utilize the knowledge of construction/destruction timing are

  • Blocks: a destructor for "stack-allocated" object is called at the end of the block

    void function()
    {  Class foo = Object(resource);
       other_operations();
    }  // destructor for foo is called here
    

  • Function calls: "stack-allocation" also happens when you call a function

    void function()
    {  another_function ( Class(resource)  );
       // destructor for the unnamed object is called
       // after another_function() returns (or throws)
       other_operations();
    }
    

  • Construction/Destruction of the containing object:

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

In STL there's a class called sentry (more exactly, istream::sentry), which implements the third pattern of those described above. So I think that is what some programmers refer to as "sentry object".

But in fact any of the above objects of class Class may be called "sentry object". They're "sentry" because they ensure that these elusive object destructors are not missed even if something throws an exception (so they are like guardians of the block/class, of sorts).

More sentry object examples are in that RAII question.


You can see a relation to aspect-oriented programming; these objects are something like "aspects", with cutpoints "at the beginning/ending of the enclosing block", "at construction/destruction of containing object" etc. But these "aspects" have to present in the code they aspectate. So they're less "aspective" compared to the original call/return functionality; instead, a sentry object should be inserted to each function of the class:

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

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

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

这篇关于什么是“哨兵对象”在C ++?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆