Resource management classes avoid directly processing resources, but many APIs directly related to resources. Therefore, functions that return original resources should be provided.
Tr1: Both shared_ptr and auto_ptr provide a get member function to execute Explicit conversions and return the original pointer (replica) inside the smart pointer ).
STD: tr1: shared_ptr <investment> pinv (createinvestment ());
Int daysheld (const investment * PI); // returns the number of days invested
Int days = daysheld (pinv); // error; the required value is "investment" and the STD: tr1: shared_ptr <investment> object is passed.
Int days = daysheld (pinv. Get () // pass the original pointer in pinv to daysheld
Almost all smart pointers overload the operator operators (operator-> and operator *) and allow implicit conversion to the original pointer at the bottom:
Class investment {
Public:
Bool istaxfree () const;
};
Investment * createinvestment ();
Void F ()
{
STD: tr1: shared_ptr <investment> pinv1 (createinvestment ());
Bool taxable =! (Pinv1-> istaxfree (); // access resources through operator->
...
STD: tr1: shared_ptr <investment> pinv2 (pinv1 );
Bool taxable2 =! (* Pinv2). istaxfree (); // access resources through operator *
...
}
Fonthandle getfont (); // c api. For simplicity, parameters are omitted
Void releasefont (fonthandle FH );
Class font
{
Public:
Explicit font (fonthandle FH)
: F (FH)
{
}
Fonthandle get () const {return F;} // explicit Conversion Function
{
Return F;
}
~ Font () {releasefont (f );}
Protected:
PRIVATE:
Fonthandle F;
};
Void changefontsize (fonthandle F, int newsize );
Font F (getfont ());
Int newfontsize;
...
Changefontsize (F. Get (), newfontsize );
Some Programmers think that Explicit conversions can be processed everywhere. Another way is to make font provide implicit conversion functions and transform them to fonthandle:
Class font
{
Public:
Explicit font (fonthandle FH)
: F (FH)
{
}
Operator fonthandle () const // implicit conversion function
{
Return F;
}
~ Font () {releasefont (f );}
Protected:
PRIVATE:
Fonthandle F;
};
In this way, it is easier for customers to call c api:
Void changefontsize (fonthandle F, int newsize );
Font F (getfont ());
Int newfontsize;
...
Changefontsize (F/*. Get () */, newfontsize); // implicitly converts a font to fonthandle
However, this implicit conversion will increase the chance of errors. For example, the customer will accidentally create a fonthandle when the font is required:
Font F1 (getfont ());
...
Fonthandle F2 = F1; // the intention is to copy a font object to manage resources.
// It implicitly converts F1 to the fonthandle at the bottom of it and then copies it.
The above fonthandle is managed by the font object F1, but the fonthandle can also be obtained by directly using F2. There is almost no such thing as F1. for example, when F1 is destroyed, the font is released, and F2 becomes a "virtual angle ).
The functions returned from the original resources in raiI class are indeed in conflict with "encapsulation", but raiI class does not exist to encapsulate something; they exist to ensure that a special behavior-resource release-will occur.