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
Funciton 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 */
}
};