SlideShare a Scribd company logo
1 of 5
Download to read offline
T
HE LAST COLUMN1
EXPLORED C++’S IDIOMATIC
approach to exception-safe acquisition and
release of resources, such as memory, file
handles, mutex locks and wait cursors. Rather
than extend the language – along with the length of
thesourcecoderequiredtomakecodesafe–C++’sexcep-
tion safety relies on a more object-oriented solution:
the resource is wrapped up in an object that automates
its release, rather than requiring the user to interlace
code with finally blocks.This refactoring has the addi-
tional, pleasant effect of reducing the amount of code
needed to work with the resource in the first place.
Scoping with exceptions
You should never see the following pattern (in the sense
of textual pattern) in your code:
{
resource_type resource = acquire();
try
{
.... // use resource, exceptions possible
}
catch(...)
{
release(resource); // clean up on exception
throw; // rethrow so caller is aware of failure
}
release(resource); // clean up on normal exit
}
It can be resolved by the following pattern (in the
sense of idiomatic design pattern):
{
scoped<resource_type, resource_releaser> resource;
.... // use resource, exceptions possible
}
Where scoped (see Listings 1, 2 and 3) was the class
template explored in the last column, and
resource_releaser is a simple function-object type
used as the clean-up policy:
struct resource_releaser
{
void operator()(resource_type resource) const
{
release(resource);
}
};
A default policy is supplied for the common case of
cleaning up memory, so the user doesn’t need to
define or explicitly supply a deleter type. However, the
use of a function-object type makes scoped more gen-
erally applicable than the standard auto_ptr class tem-
plate, which can only work in terms of pointers to single
objects and delete.This is an over-simplifying assump-
tion that’s inappropriate for many mature object
designs. For instance, an object may be allocated by
a factory rather than using new directly in the user code.
To dispose of the object, it should be returned to the
factory rather than having delete called on it directly:
class product {...};
class factory
{
public:
product *create();
void dispose(product *);
...
};
std::auto_ptr has nothing to offer us in this situa-
tion, but scoped can be parameterised easily if sup-
plied with an appropriate function-object type:
class disposer
{
public:
disposer(factory *creator)
: creator(creator)
{
}
void operator()(product *disposee)
{
creator->dispose(disposee);
}
private:
factory *creator;
};
The benefit of small classes again becomes apparent
when you see how much code you don’t need to write:
void example(factory *creator)
{
scoped<product *, disposer> ptr(
58 APPLICATION DEVELOPMENT ADVISOR q www.appdevadvisor.com
Kevlin Henney is an
independent software
development consultant
and trainer.He can be
reached at
www.curbralan.com
EFFECTIVE C++
What happens when resources change hands in C++? Kevlin Henney explains
how changing ownership of memory and file handles can be automated
efficiently and easily
One careful owner
60 APPLICATION DEVELOPMENT ADVISOR q www.appdevadvisor.com
EFFECTIVE C++
creator->create(), disposer(creator));
.... // use ptr, exceptions possible
}
When a pointer is used as the target, scoped looks and feels like
a smart pointer, supporting the appropriate operators and con-
versions.
Exchanging goods
The scoped class template is simple, but extensible and general-
purpose. In its current form, however, it is rigidly tied to always
releasing the resource it acquired at the beginning of its life.
Suppose you intend to use scoped to simplify the implementation
of a handle–body class arrangement2,3
:
class handle
{
public:
handle()
: self(new body)
{
}
handle(const handle &other)
: self(new body(*other.self))
{
}
~handle()
{
delete body;
}
....
private:
class body {....};
body *self;
....
};
On the surface, this appears to present no problems:
class handle
{
public:
handle(); // as before
handle(const handle &); // as before
~handle()
{
}
....
private:
class body {....};
scoped<body *> self;
....
};
If handle supports assignment, there’s a simple, idiomatic imple-
mentation that’s both exception and self-assignment safe for the raw
pointer version4
:
handle &operator=(const handle &rhs)
{
body *old_self = self;
self = new body(*rhs.self);
delete old_self;
return *this;
}
It’s not clear, however, how the revised version should be imple-
mented, as scoped disables assignment and has no other way of
exchanging its goods.
It’s tempting to try to figure out how to make scoped assignment
do the right thing, so that the above idiom still works. However,
as with many tempting solutions, this is the wrong one to pursue:
there are no implementations of operator= that can both satisfy user
expectations of assignment and have exclusive resource manage-
ment semantics. In a classic misuse of operator overloading,
std::auto_ptr offers such a facility:
std::auto_ptr<type> ptr(new type); // ptr is non-null
std::auto_ptr<type> qtr; // qtr is null
qtr = ptr; // qtr is non-null and ptr is null
The path towards the solution – and away from this basic vio-
lation of the principle of least astonishment (“when in doubt, do
as the ints do”5
) – comes from appreciating an alternative idiom
for writing assignment operators based on swap functions6
:
template<
typename resource_type, typename destructor = deleter>
class scoped
{
....
void swap(scoped &other)
{
std::swap(resource, other.resource);
std::swap(destruct, other.destruct);
}
....
};
Adding this feature to scoped now allows a simple and safe imple-
mentation of handle’s assignment operator:
handle &operator=(const handle &rhs)
{
handle copy(rhs); // take a copy of the RHS
self.swap(rhs.self); // exchange representations
return *this;
} // copy's destructor cleans up old representation
Premature release
The swapping technique liberalises scoped’s capabilities at no
cost to its representation. Once a scoped object has acquired a resource,
it will be released by that scoped object or one of its kin. This is
fine in most cases, but there are times when we want to use
scoped in a transactional style. For example, in the event of
failure, we want to roll back cleanly – that is, clean up resources
to avoid leaks – otherwise we want to commit to a given state and
disable any clean-up.
Consider the following exception-unsafe code:
void example(vector<type *> &ptrs)
{
ptrs.push_back(new type);
}
This is unsafe, because if the call to push_back throws an
exception from lack of memory, the newly created object will be
forgotten and lost. There are a number of workarounds, includ-
ing reserving space in advance or making the code exception-aware
(and verbose) with try and catch. Perhaps the most elegant is the
transactional style, but in its current form, scoped can’t help us
all the way:
JUNE 2001 61
EFFECTIVE C++
void example(vector<type *> &ptrs)
{
scoped<type *> ptr(new type);
ptrs.push_back(ptr);
} // object pointed to by ptr deleted... bad news for ptrs!
What is needed is a way of relieving ptr of its custodial duties
when no exceptions are thrown – something that can play the role
of a commit, like the following:
void example(vector<type *> &ptrs)
{
scoped<type *> ptr(new type);
ptrs.push_back(ptr);
ptr.release(); // commit the existence of the new object
}
The following revisions take into account this requirement, the need
for acquisition after creation, and the capability for default construction:
template<
typename resource_type, typename destructor = deleter>
class scoped
{
public: // structors
scoped()
: to_destruct(false)
{
}
explicit scoped(
resource_type resourced,
destructor on_destruct = destructor())
: to_destruct(true), ....
{
}
~scoped()
{
if(to_destruct)
destruct(resource);
}
public: // acquisition and release
void swap(scoped &other)
{
std::swap(to_destruct, other.to_destruct);
....
}
void acquire(resource_type new_resource)
{
resource_type old_resource = resource;
resource = new_resource;
if(to_destruct)
destruct(old_resource);
to_destruct = true;
}
resource_type release()
{
to_destruct = false;
return resource;
}
....
private: // representation
bool to_destruct;
....
};
Safe transfer of goods
With only a small addition to the interface, users appear to have
as much control over the behaviour of scoped as they might
need. However, there’s still one use that could be made safer – return-
ing a result from a function. In its current form, if you wish to return
a resource currently guarded by a scoped object to the caller of a
function, you have to release it and return the raw resource:
type *example()
{
scoped<type *> result(new type);
....
return result.release();
}
The caller can pick it up as follows:
type *result = example();
This appears to be fine, until you consider one constraint that
C++ does not enforce – function return values can be ignored:
example(); // memory leak
Again, the temptation is to solve the wrong problem: how can we
make scoped objects copyable so they can be used as return values?This
approach led auto_ptr into deep, hot water, endowing it with unnec-
essarily subtle, surprising and suspicious copy construction seman-
tics. For more details on the interface and implementation of auto_ptr,
see Nicolai Josuttis’s C++ Standard Library book7
.
Transfer of ownership isn’t something we should aim to hide.
Instead, it should be explicit in a function’s interface as well as in
its body. We can introduce an intermediate, proxy-like object to
represent the token of ownership. A revised version makes the own-
ership transfer more explicit:
scoped<type *>::result example()
{
scoped<type *> result(new type);
....
return result.transfer();
}
The caller’s code remains unaffected. In essence, if the tempo-
rary result object undergoes conversion, it assumes it has been picked
up and a new owner has been found for the resource. If it’s
ignored and forgotten, it will clean up the resource (see Listing 4).
As a scoped<...>::result object is passed around, the token of own-
ership is passed with it.This necessitates the use of mutable to nego-
tiate easy passage, but this const comprise is contained within its
intended usage. It’s designed for transfer purposes only, rather than
general resource management, which is the responsibility of scoped.
Simple and general
In spite of the increased complexity, arising mostly from the safe
transfer semantics, the scoped template is still simpler to use and
implement than std::auto_ptr, and is more generally applicable.
Exception safety can be mastered with relatively few idioms, but
it’s understanding interface usage and design that poses the great-
est challenges, not the mechanisms involved. It’s the challenge of
transferring ownership that turned the C++ standard library’s auto_ptr
class template into a hotbed of questionable design, turning a sim-
ple and obvious concept into something complex and subtle. The
challenge was left as an exercise for the reader at the end of the last
column. A clear separation of roles and responsibilities, making
the explicit truly explicit rather than hidden and subtle, has led
to a clearer and more responsible abstraction. s
62 APPLICATION DEVELOPMENT ADVISOR q www.appdevadvisor.com
EFFECTIVE C++
References
1. Kevlin Henney, Making an Exception, Application
Development Advisor, May 2001
2. James O Coplien, Advanced C++: Programming Styles
and Idioms, Addison-Wesley, 1992
3. Erich Gamma, Richard Helm, Ralph Johnson and
John Vlissides, Design Patterns: Elements of Reusable
Object-Oriented Software, Addison-Wesley, 1995
4. Kevlin Henney, Creating Stable Assignments, C++
Report 10(6), June 1998, is also available at
www.curbralan.com
5. Scott Meyers, More Effective C++,
Addison-Wesley, 1996
6. Herb Sutter, Exceptional C++, Addison-Wesley, 2000
7. Nicolai Josuttis, The C++ Standard Library: A Tutorial and
Reference, Addison-Wesley, 1999
Listing 1:The scoped class template for exception safety
template<
typename resource_type, typename destructor = deleter>
class scoped
{
public: // structors
explicit scoped(
resource_type resourced,
destructor on_destruct = destructor())
: resource(resourced), destruct(on_destruct)
{
}
~scoped()
{
destruct(resource);
}
public: // conversions
operator resource_type() const
{
return resource;
}
resource_type operator->() const
{
return resource;
}
dereferenced<resource_type>::type operator*() const
{
return *resource;
}
private: // prevention
scoped(const scoped &);
scoped &operator=(const scoped &);
private: // representation
resource_type resource;
destructor destruct;
};
Listing 2:The deleter function-object type for single object deletion
struct deleter
{
template<typename deleted_type>
void operator()(deleted_type to_delete) const
{
delete to_delete;
}
};
Listing 3:The dereferenced traits type for determining the return type of operator*
template<typename value_type>
struct dereferenced
JUNE 2001 63
EFFECTIVE C++
{
typedef void type;
};
template<typename element_type>
struct dereferenced<element_type *>
{
typedef element_type &type;
};
template<>
struct dereferenced<void *>
{
typedef void type;
};
Listing 4: Housekeeping after a change of ownership
template<
typename resource_type, typename destructor = deleter>
class scoped
{
....
class result
{
public: // structors and access
result(
resource_type resourced,
destructor_type on_destruct)
: to_destruct(true),
resource(resourced),
destruct(on_destruct)
{
}
result(const result &other)
: to_destruct(other.to_destruct),
resource(other.resource),
destruct(other.destruct)
{
other.to_destruct = false;
}
~transfer()
{
if(to_destruct)
destruct(resource);
}
operator resource_type()
{
to_destruct = false;
return resource;
}
private: // representation
mutable bool to_destruct;
resource_type resource;
destructor_type destruct;
};
result transfer()
{
to_destruct = false;
return result(resource, destruct);
}
....
};

More Related Content

What's hot

Insecure coding in C (and C++)
Insecure coding in C (and C++)Insecure coding in C (and C++)
Insecure coding in C (and C++)Olve Maudal
 
Coding Best Practices
Coding Best PracticesCoding Best Practices
Coding Best Practicesmh_azad
 
Detecting aspect-specific code smells using Ekeko for AspectJ
Detecting aspect-specific code smells using Ekeko for AspectJDetecting aspect-specific code smells using Ekeko for AspectJ
Detecting aspect-specific code smells using Ekeko for AspectJCoen De Roover
 
Advanced programming topics asma
Advanced programming topics asmaAdvanced programming topics asma
Advanced programming topics asmaAbdullahJana
 
Ekeko Technology Showdown at SoTeSoLa 2012
Ekeko Technology Showdown at SoTeSoLa 2012Ekeko Technology Showdown at SoTeSoLa 2012
Ekeko Technology Showdown at SoTeSoLa 2012Coen De Roover
 
A (too) Short Introduction to Scala
A (too) Short Introduction to ScalaA (too) Short Introduction to Scala
A (too) Short Introduction to ScalaRiccardo Cardin
 
Java best practices
Java best practicesJava best practices
Java best practicesRay Toal
 
The SOUL Tool Suite for Querying Programs in Symbiosis with Eclipse
The SOUL Tool Suite for Querying Programs in Symbiosis with EclipseThe SOUL Tool Suite for Querying Programs in Symbiosis with Eclipse
The SOUL Tool Suite for Querying Programs in Symbiosis with EclipseCoen De Roover
 
A Logic Meta-Programming Foundation for Example-Driven Pattern Detection in O...
A Logic Meta-Programming Foundation for Example-Driven Pattern Detection in O...A Logic Meta-Programming Foundation for Example-Driven Pattern Detection in O...
A Logic Meta-Programming Foundation for Example-Driven Pattern Detection in O...Coen De Roover
 
Unit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDDUnit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDDPaweł Michalik
 
A Recommender System for Refining Ekeko/X Transformation
A Recommender System for Refining Ekeko/X TransformationA Recommender System for Refining Ekeko/X Transformation
A Recommender System for Refining Ekeko/X TransformationCoen De Roover
 
Java căn bản - Chapter8
Java căn bản - Chapter8Java căn bản - Chapter8
Java căn bản - Chapter8Vince Vo
 
Java - Concurrent programming - Thread's basics
Java - Concurrent programming - Thread's basicsJava - Concurrent programming - Thread's basics
Java - Concurrent programming - Thread's basicsRiccardo Cardin
 
Chapter 2.4
Chapter 2.4Chapter 2.4
Chapter 2.4sotlsoc
 

What's hot (20)

Insecure coding in C (and C++)
Insecure coding in C (and C++)Insecure coding in C (and C++)
Insecure coding in C (and C++)
 
Coding Best Practices
Coding Best PracticesCoding Best Practices
Coding Best Practices
 
Detecting aspect-specific code smells using Ekeko for AspectJ
Detecting aspect-specific code smells using Ekeko for AspectJDetecting aspect-specific code smells using Ekeko for AspectJ
Detecting aspect-specific code smells using Ekeko for AspectJ
 
Advanced programming topics asma
Advanced programming topics asmaAdvanced programming topics asma
Advanced programming topics asma
 
Ekeko Technology Showdown at SoTeSoLa 2012
Ekeko Technology Showdown at SoTeSoLa 2012Ekeko Technology Showdown at SoTeSoLa 2012
Ekeko Technology Showdown at SoTeSoLa 2012
 
Thinking In Swift
Thinking In SwiftThinking In Swift
Thinking In Swift
 
A (too) Short Introduction to Scala
A (too) Short Introduction to ScalaA (too) Short Introduction to Scala
A (too) Short Introduction to Scala
 
Robots in Swift
Robots in SwiftRobots in Swift
Robots in Swift
 
Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven Development
 
Java best practices
Java best practicesJava best practices
Java best practices
 
The SOUL Tool Suite for Querying Programs in Symbiosis with Eclipse
The SOUL Tool Suite for Querying Programs in Symbiosis with EclipseThe SOUL Tool Suite for Querying Programs in Symbiosis with Eclipse
The SOUL Tool Suite for Querying Programs in Symbiosis with Eclipse
 
Deep C
Deep CDeep C
Deep C
 
A Logic Meta-Programming Foundation for Example-Driven Pattern Detection in O...
A Logic Meta-Programming Foundation for Example-Driven Pattern Detection in O...A Logic Meta-Programming Foundation for Example-Driven Pattern Detection in O...
A Logic Meta-Programming Foundation for Example-Driven Pattern Detection in O...
 
Object-oriented Basics
Object-oriented BasicsObject-oriented Basics
Object-oriented Basics
 
Unit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDDUnit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDD
 
Rhino Mocks
Rhino MocksRhino Mocks
Rhino Mocks
 
A Recommender System for Refining Ekeko/X Transformation
A Recommender System for Refining Ekeko/X TransformationA Recommender System for Refining Ekeko/X Transformation
A Recommender System for Refining Ekeko/X Transformation
 
Java căn bản - Chapter8
Java căn bản - Chapter8Java căn bản - Chapter8
Java căn bản - Chapter8
 
Java - Concurrent programming - Thread's basics
Java - Concurrent programming - Thread's basicsJava - Concurrent programming - Thread's basics
Java - Concurrent programming - Thread's basics
 
Chapter 2.4
Chapter 2.4Chapter 2.4
Chapter 2.4
 

Viewers also liked

Viewers also liked (15)

Collections for States
Collections for StatesCollections for States
Collections for States
 
The Perfect Couple
The Perfect CoupleThe Perfect Couple
The Perfect Couple
 
Worse Is Better, for Better or for Worse
Worse Is Better, for Better or for WorseWorse Is Better, for Better or for Worse
Worse Is Better, for Better or for Worse
 
Promoting Polymorphism
Promoting PolymorphismPromoting Polymorphism
Promoting Polymorphism
 
Stringing Things Along
Stringing Things AlongStringing Things Along
Stringing Things Along
 
Learning Curve
Learning CurveLearning Curve
Learning Curve
 
Inside Requirements
Inside RequirementsInside Requirements
Inside Requirements
 
Substitutability
SubstitutabilitySubstitutability
Substitutability
 
Bound and Checked
Bound and CheckedBound and Checked
Bound and Checked
 
Exceptional Naming
Exceptional NamingExceptional Naming
Exceptional Naming
 
Making Steaks from Sacred Cows
Making Steaks from Sacred CowsMaking Steaks from Sacred Cows
Making Steaks from Sacred Cows
 
Flag Waiving
Flag WaivingFlag Waiving
Flag Waiving
 
The Next Best String
The Next Best StringThe Next Best String
The Next Best String
 
Put to the Test
Put to the TestPut to the Test
Put to the Test
 
The Programmer
The ProgrammerThe Programmer
The Programmer
 

Similar to One Careful Owner

CS225_Prelecture_Notes 2nd
CS225_Prelecture_Notes 2ndCS225_Prelecture_Notes 2nd
CS225_Prelecture_Notes 2ndEdward Chen
 
New microsoft office word document (2)
New microsoft office word document (2)New microsoft office word document (2)
New microsoft office word document (2)rashmita_mishra
 
C questions
C questionsC questions
C questionsparm112
 
(3) cpp abstractions more_on_user_defined_types
(3) cpp abstractions more_on_user_defined_types(3) cpp abstractions more_on_user_defined_types
(3) cpp abstractions more_on_user_defined_typesNico Ludwig
 
Analysis of bugs in Orchard CMS
Analysis of bugs in Orchard CMSAnalysis of bugs in Orchard CMS
Analysis of bugs in Orchard CMSPVS-Studio
 
The Rest of the Best
The Rest of the BestThe Rest of the Best
The Rest of the BestKevlin Henney
 
C++ Interview Question And Answer
C++ Interview Question And AnswerC++ Interview Question And Answer
C++ Interview Question And AnswerJagan Mohan Bishoyi
 
C++ questions And Answer
C++ questions And AnswerC++ questions And Answer
C++ questions And Answerlavparmar007
 
4 pillars of OOPS CONCEPT
4 pillars of OOPS CONCEPT4 pillars of OOPS CONCEPT
4 pillars of OOPS CONCEPTAjay Chimmani
 
1183 c-interview-questions-and-answers
1183 c-interview-questions-and-answers1183 c-interview-questions-and-answers
1183 c-interview-questions-and-answersAkash Gawali
 
C, C++ Interview Questions Part - 1
C, C++ Interview Questions Part - 1C, C++ Interview Questions Part - 1
C, C++ Interview Questions Part - 1ReKruiTIn.com
 
ADK COLEGE.pptx
ADK COLEGE.pptxADK COLEGE.pptx
ADK COLEGE.pptxAshirwad2
 
C++ tutorial boost – 2013
C++ tutorial   boost – 2013C++ tutorial   boost – 2013
C++ tutorial boost – 2013Ratsietsi Mokete
 
I assignmnt(oops)
I assignmnt(oops)I assignmnt(oops)
I assignmnt(oops)Jay Patel
 
CSc investigatory project
CSc investigatory projectCSc investigatory project
CSc investigatory projectDIVYANSHU KUMAR
 
C,c++ interview q&a
C,c++ interview q&aC,c++ interview q&a
C,c++ interview q&aKumaran K
 
Oop concept in c++ by MUhammed Thanveer Melayi
Oop concept in c++ by MUhammed Thanveer MelayiOop concept in c++ by MUhammed Thanveer Melayi
Oop concept in c++ by MUhammed Thanveer MelayiMuhammed Thanveer M
 

Similar to One Careful Owner (20)

CS225_Prelecture_Notes 2nd
CS225_Prelecture_Notes 2ndCS225_Prelecture_Notes 2nd
CS225_Prelecture_Notes 2nd
 
New microsoft office word document (2)
New microsoft office word document (2)New microsoft office word document (2)
New microsoft office word document (2)
 
C questions
C questionsC questions
C questions
 
(3) cpp abstractions more_on_user_defined_types
(3) cpp abstractions more_on_user_defined_types(3) cpp abstractions more_on_user_defined_types
(3) cpp abstractions more_on_user_defined_types
 
Smart pointers
Smart pointersSmart pointers
Smart pointers
 
Analysis of bugs in Orchard CMS
Analysis of bugs in Orchard CMSAnalysis of bugs in Orchard CMS
Analysis of bugs in Orchard CMS
 
The Rest of the Best
The Rest of the BestThe Rest of the Best
The Rest of the Best
 
C++ Interview Question And Answer
C++ Interview Question And AnswerC++ Interview Question And Answer
C++ Interview Question And Answer
 
C++ questions And Answer
C++ questions And AnswerC++ questions And Answer
C++ questions And Answer
 
4 pillars of OOPS CONCEPT
4 pillars of OOPS CONCEPT4 pillars of OOPS CONCEPT
4 pillars of OOPS CONCEPT
 
1183 c-interview-questions-and-answers
1183 c-interview-questions-and-answers1183 c-interview-questions-and-answers
1183 c-interview-questions-and-answers
 
C++ Interview Questions
C++ Interview QuestionsC++ Interview Questions
C++ Interview Questions
 
C, C++ Interview Questions Part - 1
C, C++ Interview Questions Part - 1C, C++ Interview Questions Part - 1
C, C++ Interview Questions Part - 1
 
ADK COLEGE.pptx
ADK COLEGE.pptxADK COLEGE.pptx
ADK COLEGE.pptx
 
C++ tutorial boost – 2013
C++ tutorial   boost – 2013C++ tutorial   boost – 2013
C++ tutorial boost – 2013
 
I assignmnt(oops)
I assignmnt(oops)I assignmnt(oops)
I assignmnt(oops)
 
CSc investigatory project
CSc investigatory projectCSc investigatory project
CSc investigatory project
 
C,c++ interview q&a
C,c++ interview q&aC,c++ interview q&a
C,c++ interview q&a
 
Smart Pointers in C++
Smart Pointers in C++Smart Pointers in C++
Smart Pointers in C++
 
Oop concept in c++ by MUhammed Thanveer Melayi
Oop concept in c++ by MUhammed Thanveer MelayiOop concept in c++ by MUhammed Thanveer Melayi
Oop concept in c++ by MUhammed Thanveer Melayi
 

More from Kevlin Henney

The Case for Technical Excellence
The Case for Technical ExcellenceThe Case for Technical Excellence
The Case for Technical ExcellenceKevlin Henney
 
Empirical Development
Empirical DevelopmentEmpirical Development
Empirical DevelopmentKevlin Henney
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that LetterKevlin Henney
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that LetterKevlin Henney
 
Solid Deconstruction
Solid DeconstructionSolid Deconstruction
Solid DeconstructionKevlin Henney
 
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went AwayProcedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went AwayKevlin Henney
 
Structure and Interpretation of Test Cases
Structure and Interpretation of Test CasesStructure and Interpretation of Test Cases
Structure and Interpretation of Test CasesKevlin Henney
 
Refactoring to Immutability
Refactoring to ImmutabilityRefactoring to Immutability
Refactoring to ImmutabilityKevlin Henney
 
Turning Development Outside-In
Turning Development Outside-InTurning Development Outside-In
Turning Development Outside-InKevlin Henney
 
Giving Code a Good Name
Giving Code a Good NameGiving Code a Good Name
Giving Code a Good NameKevlin Henney
 
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...Kevlin Henney
 
Thinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation QuadrantThinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation QuadrantKevlin Henney
 

More from Kevlin Henney (20)

Program with GUTs
Program with GUTsProgram with GUTs
Program with GUTs
 
The Case for Technical Excellence
The Case for Technical ExcellenceThe Case for Technical Excellence
The Case for Technical Excellence
 
Empirical Development
Empirical DevelopmentEmpirical Development
Empirical Development
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
 
Solid Deconstruction
Solid DeconstructionSolid Deconstruction
Solid Deconstruction
 
Get Kata
Get KataGet Kata
Get Kata
 
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went AwayProcedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
 
Structure and Interpretation of Test Cases
Structure and Interpretation of Test CasesStructure and Interpretation of Test Cases
Structure and Interpretation of Test Cases
 
Agility ≠ Speed
Agility ≠ SpeedAgility ≠ Speed
Agility ≠ Speed
 
Refactoring to Immutability
Refactoring to ImmutabilityRefactoring to Immutability
Refactoring to Immutability
 
Old Is the New New
Old Is the New NewOld Is the New New
Old Is the New New
 
Turning Development Outside-In
Turning Development Outside-InTurning Development Outside-In
Turning Development Outside-In
 
Giving Code a Good Name
Giving Code a Good NameGiving Code a Good Name
Giving Code a Good Name
 
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
 
Thinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation QuadrantThinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation Quadrant
 
Code as Risk
Code as RiskCode as Risk
Code as Risk
 
Software Is Details
Software Is DetailsSoftware Is Details
Software Is Details
 
Game of Sprints
Game of SprintsGame of Sprints
Game of Sprints
 
Good Code
Good CodeGood Code
Good Code
 

Recently uploaded

WSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2
 
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfonteinmasabamasaba
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...Jittipong Loespradit
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyviewmasabamasaba
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...masabamasaba
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrainmasabamasaba
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...masabamasaba
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...masabamasaba
 
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benonimasabamasaba
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisamasabamasaba
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park masabamasaba
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnAmarnathKambale
 
WSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrandmasabamasaba
 
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburgmasabamasaba
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Bert Jan Schrijver
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfonteinmasabamasaba
 

Recently uploaded (20)

WSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaS
 
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
 
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
WSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - Keynote
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 

One Careful Owner

  • 1. T HE LAST COLUMN1 EXPLORED C++’S IDIOMATIC approach to exception-safe acquisition and release of resources, such as memory, file handles, mutex locks and wait cursors. Rather than extend the language – along with the length of thesourcecoderequiredtomakecodesafe–C++’sexcep- tion safety relies on a more object-oriented solution: the resource is wrapped up in an object that automates its release, rather than requiring the user to interlace code with finally blocks.This refactoring has the addi- tional, pleasant effect of reducing the amount of code needed to work with the resource in the first place. Scoping with exceptions You should never see the following pattern (in the sense of textual pattern) in your code: { resource_type resource = acquire(); try { .... // use resource, exceptions possible } catch(...) { release(resource); // clean up on exception throw; // rethrow so caller is aware of failure } release(resource); // clean up on normal exit } It can be resolved by the following pattern (in the sense of idiomatic design pattern): { scoped<resource_type, resource_releaser> resource; .... // use resource, exceptions possible } Where scoped (see Listings 1, 2 and 3) was the class template explored in the last column, and resource_releaser is a simple function-object type used as the clean-up policy: struct resource_releaser { void operator()(resource_type resource) const { release(resource); } }; A default policy is supplied for the common case of cleaning up memory, so the user doesn’t need to define or explicitly supply a deleter type. However, the use of a function-object type makes scoped more gen- erally applicable than the standard auto_ptr class tem- plate, which can only work in terms of pointers to single objects and delete.This is an over-simplifying assump- tion that’s inappropriate for many mature object designs. For instance, an object may be allocated by a factory rather than using new directly in the user code. To dispose of the object, it should be returned to the factory rather than having delete called on it directly: class product {...}; class factory { public: product *create(); void dispose(product *); ... }; std::auto_ptr has nothing to offer us in this situa- tion, but scoped can be parameterised easily if sup- plied with an appropriate function-object type: class disposer { public: disposer(factory *creator) : creator(creator) { } void operator()(product *disposee) { creator->dispose(disposee); } private: factory *creator; }; The benefit of small classes again becomes apparent when you see how much code you don’t need to write: void example(factory *creator) { scoped<product *, disposer> ptr( 58 APPLICATION DEVELOPMENT ADVISOR q www.appdevadvisor.com Kevlin Henney is an independent software development consultant and trainer.He can be reached at www.curbralan.com EFFECTIVE C++ What happens when resources change hands in C++? Kevlin Henney explains how changing ownership of memory and file handles can be automated efficiently and easily One careful owner
  • 2. 60 APPLICATION DEVELOPMENT ADVISOR q www.appdevadvisor.com EFFECTIVE C++ creator->create(), disposer(creator)); .... // use ptr, exceptions possible } When a pointer is used as the target, scoped looks and feels like a smart pointer, supporting the appropriate operators and con- versions. Exchanging goods The scoped class template is simple, but extensible and general- purpose. In its current form, however, it is rigidly tied to always releasing the resource it acquired at the beginning of its life. Suppose you intend to use scoped to simplify the implementation of a handle–body class arrangement2,3 : class handle { public: handle() : self(new body) { } handle(const handle &other) : self(new body(*other.self)) { } ~handle() { delete body; } .... private: class body {....}; body *self; .... }; On the surface, this appears to present no problems: class handle { public: handle(); // as before handle(const handle &); // as before ~handle() { } .... private: class body {....}; scoped<body *> self; .... }; If handle supports assignment, there’s a simple, idiomatic imple- mentation that’s both exception and self-assignment safe for the raw pointer version4 : handle &operator=(const handle &rhs) { body *old_self = self; self = new body(*rhs.self); delete old_self; return *this; } It’s not clear, however, how the revised version should be imple- mented, as scoped disables assignment and has no other way of exchanging its goods. It’s tempting to try to figure out how to make scoped assignment do the right thing, so that the above idiom still works. However, as with many tempting solutions, this is the wrong one to pursue: there are no implementations of operator= that can both satisfy user expectations of assignment and have exclusive resource manage- ment semantics. In a classic misuse of operator overloading, std::auto_ptr offers such a facility: std::auto_ptr<type> ptr(new type); // ptr is non-null std::auto_ptr<type> qtr; // qtr is null qtr = ptr; // qtr is non-null and ptr is null The path towards the solution – and away from this basic vio- lation of the principle of least astonishment (“when in doubt, do as the ints do”5 ) – comes from appreciating an alternative idiom for writing assignment operators based on swap functions6 : template< typename resource_type, typename destructor = deleter> class scoped { .... void swap(scoped &other) { std::swap(resource, other.resource); std::swap(destruct, other.destruct); } .... }; Adding this feature to scoped now allows a simple and safe imple- mentation of handle’s assignment operator: handle &operator=(const handle &rhs) { handle copy(rhs); // take a copy of the RHS self.swap(rhs.self); // exchange representations return *this; } // copy's destructor cleans up old representation Premature release The swapping technique liberalises scoped’s capabilities at no cost to its representation. Once a scoped object has acquired a resource, it will be released by that scoped object or one of its kin. This is fine in most cases, but there are times when we want to use scoped in a transactional style. For example, in the event of failure, we want to roll back cleanly – that is, clean up resources to avoid leaks – otherwise we want to commit to a given state and disable any clean-up. Consider the following exception-unsafe code: void example(vector<type *> &ptrs) { ptrs.push_back(new type); } This is unsafe, because if the call to push_back throws an exception from lack of memory, the newly created object will be forgotten and lost. There are a number of workarounds, includ- ing reserving space in advance or making the code exception-aware (and verbose) with try and catch. Perhaps the most elegant is the transactional style, but in its current form, scoped can’t help us all the way:
  • 3. JUNE 2001 61 EFFECTIVE C++ void example(vector<type *> &ptrs) { scoped<type *> ptr(new type); ptrs.push_back(ptr); } // object pointed to by ptr deleted... bad news for ptrs! What is needed is a way of relieving ptr of its custodial duties when no exceptions are thrown – something that can play the role of a commit, like the following: void example(vector<type *> &ptrs) { scoped<type *> ptr(new type); ptrs.push_back(ptr); ptr.release(); // commit the existence of the new object } The following revisions take into account this requirement, the need for acquisition after creation, and the capability for default construction: template< typename resource_type, typename destructor = deleter> class scoped { public: // structors scoped() : to_destruct(false) { } explicit scoped( resource_type resourced, destructor on_destruct = destructor()) : to_destruct(true), .... { } ~scoped() { if(to_destruct) destruct(resource); } public: // acquisition and release void swap(scoped &other) { std::swap(to_destruct, other.to_destruct); .... } void acquire(resource_type new_resource) { resource_type old_resource = resource; resource = new_resource; if(to_destruct) destruct(old_resource); to_destruct = true; } resource_type release() { to_destruct = false; return resource; } .... private: // representation bool to_destruct; .... }; Safe transfer of goods With only a small addition to the interface, users appear to have as much control over the behaviour of scoped as they might need. However, there’s still one use that could be made safer – return- ing a result from a function. In its current form, if you wish to return a resource currently guarded by a scoped object to the caller of a function, you have to release it and return the raw resource: type *example() { scoped<type *> result(new type); .... return result.release(); } The caller can pick it up as follows: type *result = example(); This appears to be fine, until you consider one constraint that C++ does not enforce – function return values can be ignored: example(); // memory leak Again, the temptation is to solve the wrong problem: how can we make scoped objects copyable so they can be used as return values?This approach led auto_ptr into deep, hot water, endowing it with unnec- essarily subtle, surprising and suspicious copy construction seman- tics. For more details on the interface and implementation of auto_ptr, see Nicolai Josuttis’s C++ Standard Library book7 . Transfer of ownership isn’t something we should aim to hide. Instead, it should be explicit in a function’s interface as well as in its body. We can introduce an intermediate, proxy-like object to represent the token of ownership. A revised version makes the own- ership transfer more explicit: scoped<type *>::result example() { scoped<type *> result(new type); .... return result.transfer(); } The caller’s code remains unaffected. In essence, if the tempo- rary result object undergoes conversion, it assumes it has been picked up and a new owner has been found for the resource. If it’s ignored and forgotten, it will clean up the resource (see Listing 4). As a scoped<...>::result object is passed around, the token of own- ership is passed with it.This necessitates the use of mutable to nego- tiate easy passage, but this const comprise is contained within its intended usage. It’s designed for transfer purposes only, rather than general resource management, which is the responsibility of scoped. Simple and general In spite of the increased complexity, arising mostly from the safe transfer semantics, the scoped template is still simpler to use and implement than std::auto_ptr, and is more generally applicable. Exception safety can be mastered with relatively few idioms, but it’s understanding interface usage and design that poses the great- est challenges, not the mechanisms involved. It’s the challenge of transferring ownership that turned the C++ standard library’s auto_ptr class template into a hotbed of questionable design, turning a sim- ple and obvious concept into something complex and subtle. The challenge was left as an exercise for the reader at the end of the last column. A clear separation of roles and responsibilities, making the explicit truly explicit rather than hidden and subtle, has led to a clearer and more responsible abstraction. s
  • 4. 62 APPLICATION DEVELOPMENT ADVISOR q www.appdevadvisor.com EFFECTIVE C++ References 1. Kevlin Henney, Making an Exception, Application Development Advisor, May 2001 2. James O Coplien, Advanced C++: Programming Styles and Idioms, Addison-Wesley, 1992 3. Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Design Patterns: Elements of Reusable Object-Oriented Software, Addison-Wesley, 1995 4. Kevlin Henney, Creating Stable Assignments, C++ Report 10(6), June 1998, is also available at www.curbralan.com 5. Scott Meyers, More Effective C++, Addison-Wesley, 1996 6. Herb Sutter, Exceptional C++, Addison-Wesley, 2000 7. Nicolai Josuttis, The C++ Standard Library: A Tutorial and Reference, Addison-Wesley, 1999 Listing 1:The scoped class template for exception safety template< typename resource_type, typename destructor = deleter> class scoped { public: // structors explicit scoped( resource_type resourced, destructor on_destruct = destructor()) : resource(resourced), destruct(on_destruct) { } ~scoped() { destruct(resource); } public: // conversions operator resource_type() const { return resource; } resource_type operator->() const { return resource; } dereferenced<resource_type>::type operator*() const { return *resource; } private: // prevention scoped(const scoped &); scoped &operator=(const scoped &); private: // representation resource_type resource; destructor destruct; }; Listing 2:The deleter function-object type for single object deletion struct deleter { template<typename deleted_type> void operator()(deleted_type to_delete) const { delete to_delete; } }; Listing 3:The dereferenced traits type for determining the return type of operator* template<typename value_type> struct dereferenced
  • 5. JUNE 2001 63 EFFECTIVE C++ { typedef void type; }; template<typename element_type> struct dereferenced<element_type *> { typedef element_type &type; }; template<> struct dereferenced<void *> { typedef void type; }; Listing 4: Housekeeping after a change of ownership template< typename resource_type, typename destructor = deleter> class scoped { .... class result { public: // structors and access result( resource_type resourced, destructor_type on_destruct) : to_destruct(true), resource(resourced), destruct(on_destruct) { } result(const result &other) : to_destruct(other.to_destruct), resource(other.resource), destruct(other.destruct) { other.to_destruct = false; } ~transfer() { if(to_destruct) destruct(resource); } operator resource_type() { to_destruct = false; return resource; } private: // representation mutable bool to_destruct; resource_type resource; destructor_type destruct; }; result transfer() { to_destruct = false; return result(resource, destruct); } .... };