2242 lines
234 KiB
HTML
2242 lines
234 KiB
HTML
<html>
|
||
<head>
|
||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||
<title>Tutorial</title>
|
||
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
|
||
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
|
||
<link rel="home" href="../index.html" title="Chapter 1. Boost.Contract 1.0.0">
|
||
<link rel="up" href="../index.html" title="Chapter 1. Boost.Contract 1.0.0">
|
||
<link rel="prev" href="contract_programming_overview.html" title="Contract Programming Overview">
|
||
<link rel="next" href="advanced.html" title="Advanced">
|
||
</head>
|
||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||
<table cellpadding="2" width="100%"><tr>
|
||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
|
||
<td align="center"><a href="../../../../../index.html">Home</a></td>
|
||
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
|
||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
|
||
</tr></table>
|
||
<hr>
|
||
<div class="spirit-nav">
|
||
<a accesskey="p" href="contract_programming_overview.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="advanced.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||
<a name="boost_contract.tutorial"></a><a class="link" href="tutorial.html" title="Tutorial">Tutorial</a>
|
||
</h2></div></div></div>
|
||
<div class="toc"><dl class="toc">
|
||
<dt><span class="section"><a href="tutorial.html#boost_contract.tutorial.non_member_functions">Non-Member
|
||
Functions</a></span></dt>
|
||
<dt><span class="section"><a href="tutorial.html#boost_contract.tutorial.preconditions">Preconditions</a></span></dt>
|
||
<dt><span class="section"><a href="tutorial.html#boost_contract.tutorial.postconditions">Postconditions</a></span></dt>
|
||
<dt><span class="section"><a href="tutorial.html#boost_contract.tutorial.return_values">Return Values</a></span></dt>
|
||
<dt><span class="section"><a href="tutorial.html#boost_contract.tutorial.old_values">Old Values</a></span></dt>
|
||
<dt><span class="section"><a href="tutorial.html#boost_contract.tutorial.exception_guarantees">Exception
|
||
Guarantees</a></span></dt>
|
||
<dt><span class="section"><a href="tutorial.html#boost_contract.tutorial.class_invariants">Class Invariants</a></span></dt>
|
||
<dt><span class="section"><a href="tutorial.html#boost_contract.tutorial.constructors">Constructors</a></span></dt>
|
||
<dt><span class="section"><a href="tutorial.html#boost_contract.tutorial.destructors">Destructors</a></span></dt>
|
||
<dt><span class="section"><a href="tutorial.html#boost_contract.tutorial.public_functions">Public Functions</a></span></dt>
|
||
<dt><span class="section"><a href="tutorial.html#boost_contract.tutorial.virtual_public_functions">Virtual
|
||
Public Functions</a></span></dt>
|
||
<dt><span class="section"><a href="tutorial.html#boost_contract.tutorial.public_function_overrides__subcontracting_">Public
|
||
Function Overrides (Subcontracting)</a></span></dt>
|
||
<dt><span class="section"><a href="tutorial.html#boost_contract.tutorial.base_classes__subcontracting_">Base
|
||
Classes (Subcontracting)</a></span></dt>
|
||
<dt><span class="section"><a href="tutorial.html#boost_contract.tutorial.static_public_functions">Static
|
||
Public Functions</a></span></dt>
|
||
</dl></div>
|
||
<p>
|
||
This section is a guide to basic usage of this library.
|
||
</p>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="boost_contract.tutorial.non_member_functions"></a><a class="link" href="tutorial.html#boost_contract.tutorial.non_member_functions" title="Non-Member Functions">Non-Member
|
||
Functions</a>
|
||
</h3></div></div></div>
|
||
<p>
|
||
Contracts for non-member functions are programmed using <code class="computeroutput"><a class="link" href="../boost/contract/function.html" title="Function function">boost::contract::function</a></code>.
|
||
For example (see <a href="../../../example/features/non_member.cpp" target="_top"><code class="literal">non_member.cpp</code></a>):
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">contract</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
|
||
<span class="comment">// Contract for a non-member function.</span>
|
||
<span class="keyword">int</span> <span class="identifier">inc</span><span class="special">(</span><span class="keyword">int</span><span class="special">&</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span>
|
||
<span class="keyword">int</span> <span class="identifier">result</span><span class="special">;</span>
|
||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_ptr</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">old_x</span> <span class="special">=</span> <span class="identifier">BOOST_CONTRACT_OLDOF</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span>
|
||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">function</span><span class="special">()</span>
|
||
<span class="special">.</span><span class="identifier">precondition</span><span class="special">([&]</span> <span class="special">{</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">x</span> <span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">int</span><span class="special">>::</span><span class="identifier">max</span><span class="special">());</span>
|
||
<span class="special">})</span>
|
||
<span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">{</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">x</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">old_x</span> <span class="special">+</span> <span class="number">1</span><span class="special">);</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">result</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">old_x</span><span class="special">);</span>
|
||
<span class="special">})</span>
|
||
<span class="special">.</span><span class="identifier">except</span><span class="special">([&]</span> <span class="special">{</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">x</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">old_x</span><span class="special">);</span>
|
||
<span class="special">})</span>
|
||
<span class="special">;</span>
|
||
|
||
<span class="keyword">return</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">++;</span> <span class="comment">// Function body.</span>
|
||
<span class="special">}</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
All necessary header files of this library are included by <code class="computeroutput"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">contract</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span></code>.
|
||
Alternatively, programmers can selectively include only the header files
|
||
they actually need among <code class="literal">boost/contract/*.hpp</code> (see <a class="link" href="getting_started.html" title="Getting Started">Getting Started</a>).
|
||
</p>
|
||
<p>
|
||
It is possible to specify preconditions, postconditions, and exception guarantees
|
||
for non-member functions (see <a class="link" href="tutorial.html#boost_contract.tutorial.preconditions" title="Preconditions">Preconditions</a>,
|
||
<a class="link" href="tutorial.html#boost_contract.tutorial.postconditions" title="Postconditions">Postconditions</a>,
|
||
and <a class="link" href="tutorial.html#boost_contract.tutorial.exception_guarantees" title="Exception Guarantees">Exception
|
||
Guarantees</a>).
|
||
</p>
|
||
<p>
|
||
The <code class="computeroutput"><a class="link" href="../boost/contract/function.html" title="Function function">boost::contract::function</a></code>
|
||
function returns an RAII object that must always be assigned to a local variable
|
||
of type <code class="computeroutput"><a class="link" href="../boost/contract/check.html" title="Class check">boost::contract::check</a></code>
|
||
(otherwise this library will generate a run-time error, see <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45028039691696.html" title="Macro BOOST_CONTRACT_ON_MISSING_CHECK_DECL">BOOST_CONTRACT_ON_MISSING_CHECK_DECL</a></code>).
|
||
<a href="#ftn.boost_contract.tutorial.non_member_functions.f0" class="footnote" name="boost_contract.tutorial.non_member_functions.f0"><sup class="footnote">[19]</sup></a> Furthermore, C++11 <code class="computeroutput"><span class="keyword">auto</span></code>
|
||
declarations cannot be used here and the <code class="computeroutput"><a class="link" href="../boost/contract/check.html" title="Class check">boost::contract::check</a></code>
|
||
type must be explicitly specified (otherwise this library will generate a
|
||
compile-time error prior C++17 and a run-time error post C++17). <a href="#ftn.boost_contract.tutorial.non_member_functions.f1" class="footnote" name="boost_contract.tutorial.non_member_functions.f1"><sup class="footnote">[20]</sup></a> The function body is programmed right after the declaration of
|
||
this RAII object.
|
||
</p>
|
||
<div class="note"><table border="0" summary="Note">
|
||
<tr>
|
||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
|
||
<th align="left">Note</th>
|
||
</tr>
|
||
<tr><td align="left" valign="top"><p>
|
||
In some cases, it might be necessary to program some code before the contract.
|
||
For example for acquiring resources that will be used while checking the
|
||
contract like old values, but also to lock mutexes (or other synchronization
|
||
mechanisms) in multi-threaded programs.
|
||
</p></td></tr>
|
||
</table></div>
|
||
<p>
|
||
At construction, the <code class="computeroutput"><a class="link" href="../boost/contract/check.html" title="Class check">boost::contract::check</a></code>
|
||
RAII object for non-member functions does the following (enclosing function
|
||
entry):
|
||
</p>
|
||
<div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">
|
||
Check preconditions, by calling the nullary functor <code class="literal"><span class="emphasis"><em>r</em></span></code><code class="computeroutput"><span class="special">()</span></code> passed to <code class="computeroutput"><span class="special">.</span><span class="identifier">precondition</span><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>r</em></span></code><code class="computeroutput"><span class="special">)</span></code>.
|
||
</li></ol></div>
|
||
<p>
|
||
At destruction instead (enclosing function exit):
|
||
</p>
|
||
<div class="orderedlist"><ol class="orderedlist" type="1">
|
||
<li class="listitem">
|
||
If the function body did not throw an exception:
|
||
<div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem">
|
||
Check postconditions, by calling the nullary functor <code class="literal"><span class="emphasis"><em>s</em></span></code><code class="computeroutput"><span class="special">()</span></code> passed to <code class="computeroutput"><span class="special">.</span><span class="identifier">postcondition</span><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>s</em></span></code><code class="computeroutput"><span class="special">)</span></code>.
|
||
</li></ol></div>
|
||
</li>
|
||
<li class="listitem">
|
||
Else:
|
||
<div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem">
|
||
Check exception guarantees, by calling the nullary functor <code class="literal"><span class="emphasis"><em>e</em></span></code><code class="computeroutput"><span class="special">()</span></code> passed to <code class="computeroutput"><span class="special">.</span><span class="identifier">except</span><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>e</em></span></code><code class="computeroutput"><span class="special">)</span></code>.
|
||
</li></ol></div>
|
||
</li>
|
||
</ol></div>
|
||
<p>
|
||
This ensures that non-member function contracts are correctly checked at
|
||
run-time (see <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.function_calls" title="Function Calls">Function
|
||
Calls</a>). (Also note that functions will correctly check their contracts
|
||
even when they are called via function pointers, function objects, etc.)
|
||
</p>
|
||
<div class="note"><table border="0" summary="Note">
|
||
<tr>
|
||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
|
||
<th align="left">Note</th>
|
||
</tr>
|
||
<tr><td align="left" valign="top"><p>
|
||
A non-member function can avoid calling <code class="computeroutput"><a class="link" href="../boost/contract/function.html" title="Function function">boost::contract::function</a></code>
|
||
for efficiency but only when it has no preconditions, no postconditions,
|
||
and no exception guarantees.
|
||
</p></td></tr>
|
||
</table></div>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="boost_contract.tutorial.preconditions"></a><a class="link" href="tutorial.html#boost_contract.tutorial.preconditions" title="Preconditions">Preconditions</a>
|
||
</h3></div></div></div>
|
||
<p>
|
||
When preconditions are specified, they are programmed using a functor <code class="literal"><span class="emphasis"><em>r</em></span></code>
|
||
passed to <code class="computeroutput"><span class="special">.</span><span class="identifier">precondition</span><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>r</em></span></code><code class="computeroutput"><span class="special">)</span></code> that can be called with no parameters as
|
||
in <code class="literal"><span class="emphasis"><em>r</em></span></code><code class="computeroutput"><span class="special">()</span></code>.
|
||
Contracts that do not have preconditions simply do not call <code class="computeroutput"><span class="special">.</span><span class="identifier">precondition</span><span class="special">(...)</span></code>. Preconditions must appear before postconditions
|
||
and exception guarantees when these are all present (see <a class="link" href="tutorial.html#boost_contract.tutorial.postconditions" title="Postconditions">Postconditions</a>
|
||
and <a class="link" href="tutorial.html#boost_contract.tutorial.exception_guarantees" title="Exception Guarantees">Exception
|
||
Guarantees</a>).
|
||
</p>
|
||
<p>
|
||
C++11 lambda functions are convenient to program preconditions, but any other
|
||
nullary functor can be used (see <a class="link" href="extras.html#boost_contract.extras.no_lambda_functions__no_c__11_" title="No Lambda Functions (No C++11)">No
|
||
Lambda Functions</a>). <a href="#ftn.boost_contract.tutorial.preconditions.f0" class="footnote" name="boost_contract.tutorial.preconditions.f0"><sup class="footnote">[21]</sup></a> For example, for <code class="computeroutput"><a class="link" href="../boost/contract/function.html" title="Function function">boost::contract::function</a></code>
|
||
(similarly for public functions, instead destructors do not have preconditions
|
||
and constructors use <code class="computeroutput"><a class="link" href="../boost/contract/constructor_precondition.html" title="Class template constructor_precondition">boost::contract::constructor_precondition</a></code>,
|
||
see <a class="link" href="tutorial.html#boost_contract.tutorial.public_functions" title="Public Functions">Public Functions</a>,
|
||
<a class="link" href="tutorial.html#boost_contract.tutorial.destructors" title="Destructors">Destructors</a>, and
|
||
<a class="link" href="tutorial.html#boost_contract.tutorial.constructors" title="Constructors">Constructors</a>):
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">f</span><span class="special">(...)</span> <span class="special">{</span>
|
||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">function</span><span class="special">()</span> <span class="comment">// Same for all other contracts.</span>
|
||
<span class="special">.</span><span class="identifier">precondition</span><span class="special">([&]</span> <span class="special">{</span> <span class="comment">// Capture by reference or value...</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(...);</span> <span class="comment">// ...and should not modify captures.</span>
|
||
<span class="special">...</span>
|
||
<span class="special">})</span>
|
||
<span class="special">...</span>
|
||
<span class="special">;</span>
|
||
|
||
<span class="special">...</span>
|
||
<span class="special">}</span>
|
||
</pre>
|
||
<p>
|
||
The precondition functor should capture all the variables that it needs to
|
||
assert the preconditions. These variables can be captured by value when the
|
||
overhead of copying such variables is acceptable. <a href="#ftn.boost_contract.tutorial.preconditions.f1" class="footnote" name="boost_contract.tutorial.preconditions.f1"><sup class="footnote">[22]</sup></a> In any case, programmers should not write precondition assertions
|
||
that modify the value of the captured variables, even when those are captured
|
||
by reference (see <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.constant_correctness" title="Constant-Correctness">Constant-Correctness</a>).
|
||
</p>
|
||
<p>
|
||
Any code can be programmed in the precondition functor, but it is recommended
|
||
to keep this code simple using mainly assertions and if-statements (to avoid
|
||
programming complex preconditions that might be buggy and also slow to check
|
||
at run-time). It is also recommended to use <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_ASSERT.html" title="Macro BOOST_CONTRACT_ASSERT">BOOST_CONTRACT_ASSERT</a></code>
|
||
to program precondition assertions because that enables this library to print
|
||
informative error messages when the asserted conditions are evaluated to
|
||
be false (note that this is not a variadic macro, see <a class="link" href="extras.html#boost_contract.extras.no_macros__and_no_variadic_macros_" title="No Macros (and No Variadic Macros)">No
|
||
Macros</a>):
|
||
</p>
|
||
<pre class="programlisting"><span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><code class="literal"><span class="emphasis"><em>boolean-condition</em></span></code><span class="special">)</span>
|
||
<span class="comment">// Or, if `boolean-condition` contains commas `,` not already within parenthesis `()`...</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">((</span><code class="literal"><span class="emphasis"><em>boolean-condition</em></span></code><span class="special">))</span> <span class="comment">// ...use extra parenthesis (not a variadic macro).</span>
|
||
</pre>
|
||
<p>
|
||
This library will automatically call the failure handler <code class="computeroutput"><a class="link" href="../boost/contract/precondition_failure.html" title="Function precondition_failure">boost::contract::precondition_failure</a></code>
|
||
if any of the <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_ASSERT.html" title="Macro BOOST_CONTRACT_ASSERT">BOOST_CONTRACT_ASSERT</a></code>
|
||
conditions are false or, more in general, if calling the functor specified
|
||
via <code class="computeroutput"><span class="special">.</span><span class="identifier">precondition</span><span class="special">(...)</span></code> throws any exception. By default, this
|
||
failure handler prints an error message to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cerr</span></code>
|
||
and terminates the program calling <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">terminate</span></code>
|
||
(see <a class="link" href="advanced.html#boost_contract.advanced.throw_on_failures__and__noexcept__" title="Throw on Failures (and noexcept)">Throw
|
||
on Failures</a> to change the failure handler to throw exceptions, exit
|
||
the program with an error code, etc.).
|
||
</p>
|
||
<div class="note"><table border="0" summary="Note">
|
||
<tr>
|
||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
|
||
<th align="left">Note</th>
|
||
</tr>
|
||
<tr><td align="left" valign="top"><p>
|
||
Contracts are most useful when their assertions only use public members
|
||
that are accessible to the caller so the caller can properly check and
|
||
use the contract. In particular, preconditions of a public function or
|
||
constructor that use non-public members are essentially incorrect because
|
||
they cannot be fully checked by the caller (in fact, Eiffel generates a
|
||
compile-time error in this case). However, this library does not enforce
|
||
such a constraint and it leaves it up to programmers to only use public
|
||
members when programming contracts, especially when asserting preconditions
|
||
(see <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.specifications_vs__implementation" title="Specifications vs. Implementation">Specifications
|
||
vs. Implementation</a>).
|
||
</p></td></tr>
|
||
</table></div>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="boost_contract.tutorial.postconditions"></a><a class="link" href="tutorial.html#boost_contract.tutorial.postconditions" title="Postconditions">Postconditions</a>
|
||
</h3></div></div></div>
|
||
<p>
|
||
When postconditions are specified, they are programmed using a functor <code class="literal"><span class="emphasis"><em>s</em></span></code>
|
||
passed to <code class="computeroutput"><span class="special">.</span><span class="identifier">postcondition</span><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>s</em></span></code><code class="computeroutput"><span class="special">)</span></code> that can be called with no parameters as
|
||
in <code class="literal"><span class="emphasis"><em>s</em></span></code><code class="computeroutput"><span class="special">()</span></code>.
|
||
Contracts that do not have postconditions simply do not call <code class="computeroutput"><span class="special">.</span><span class="identifier">postcondition</span><span class="special">(...)</span></code>. Postconditions must appear after preconditions
|
||
but before exception guarantees when these are all present (see <a class="link" href="tutorial.html#boost_contract.tutorial.preconditions" title="Preconditions">Preconditions</a>
|
||
and <a class="link" href="tutorial.html#boost_contract.tutorial.exception_guarantees" title="Exception Guarantees">Exception
|
||
Guarantees</a>).
|
||
</p>
|
||
<p>
|
||
C++11 lambda functions are convenient to program postconditions, but any
|
||
other nullary functor can be used (see <a class="link" href="extras.html#boost_contract.extras.no_lambda_functions__no_c__11_" title="No Lambda Functions (No C++11)">No
|
||
Lambda Functions</a>). For example, for <code class="computeroutput"><a class="link" href="../boost/contract/function.html" title="Function function">boost::contract::function</a></code>
|
||
(similarly for all other contracts):
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">f</span><span class="special">(...)</span> <span class="special">{</span>
|
||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">function</span><span class="special">()</span> <span class="comment">// Same for all other contracts.</span>
|
||
<span class="special">...</span>
|
||
<span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">{</span> <span class="comment">// Capture by reference...</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(...);</span> <span class="comment">// ...but should not modify captures.</span>
|
||
<span class="special">...</span>
|
||
<span class="special">})</span>
|
||
<span class="special">...</span>
|
||
<span class="special">;</span>
|
||
|
||
<span class="special">...</span>
|
||
<span class="special">}</span>
|
||
</pre>
|
||
<p>
|
||
The postcondition functor should capture all the variables that it needs
|
||
to assert the postconditions. In general, these variables should be captured
|
||
by reference and not by value (because postconditions need to access the
|
||
value that these variables will have at function exit, and not the value
|
||
these variables had when the postcondition functor was first declared). Postconditions
|
||
can also capture return and old values (see <a class="link" href="tutorial.html#boost_contract.tutorial.return_values" title="Return Values">Return
|
||
Values</a> and <a class="link" href="tutorial.html#boost_contract.tutorial.old_values" title="Old Values">Old
|
||
Values</a>). In any case, programmers should not write postcondition assertions
|
||
that modify the value of the captured variables, even when those are captured
|
||
by reference (see <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.constant_correctness" title="Constant-Correctness">Constant-Correctness</a>).
|
||
</p>
|
||
<p>
|
||
Any code can be programmed in the postcondition functor, but it is recommended
|
||
to keep this code simple using mainly assertions and if-statements (to avoid
|
||
programming complex postconditions that might be buggy and slow to check
|
||
at run-time). It is also recommended to use <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_ASSERT.html" title="Macro BOOST_CONTRACT_ASSERT">BOOST_CONTRACT_ASSERT</a></code>
|
||
to program postcondition assertions because that enables this library to
|
||
print informative error messages when the asserted conditions are evaluated
|
||
to be false (note that this is not a variadic macro, see <a class="link" href="extras.html#boost_contract.extras.no_macros__and_no_variadic_macros_" title="No Macros (and No Variadic Macros)">No
|
||
Macros</a>):
|
||
</p>
|
||
<pre class="programlisting"><span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><code class="literal"><span class="emphasis"><em>boolean-condition</em></span></code><span class="special">)</span>
|
||
<span class="comment">// Or, if `boolean-condition` has commas `,` not already within parenthesis `()`...</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">((</span><code class="literal"><span class="emphasis"><em>boolean-condition</em></span></code><span class="special">))</span> <span class="comment">// ...use extra parenthesis (not a variadic macro).</span>
|
||
</pre>
|
||
<p>
|
||
This library will automatically call the failure handler <code class="computeroutput"><a class="link" href="../boost/contract/postcondition_failure.html" title="Function postcondition_failure">boost::contract::postcondition_failure</a></code>
|
||
if any of the <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_ASSERT.html" title="Macro BOOST_CONTRACT_ASSERT">BOOST_CONTRACT_ASSERT</a></code>
|
||
conditions are false or, more in general, if calling the functor specified
|
||
via <code class="computeroutput"><span class="special">.</span><span class="identifier">postcondition</span><span class="special">(...)</span></code> throws any exception. By default, this
|
||
failure handler prints an error message to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cerr</span></code>
|
||
and terminates the program calling <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">terminate</span></code>
|
||
(see <a class="link" href="advanced.html#boost_contract.advanced.throw_on_failures__and__noexcept__" title="Throw on Failures (and noexcept)">Throw
|
||
on Failures</a> to change the failure handler to throw exceptions, exit
|
||
the program with an error code, etc.).
|
||
</p>
|
||
<p>
|
||
For non-void virtual public functions and non-void public function overrides,
|
||
the functor <code class="literal"><span class="emphasis"><em>s</em></span></code> passed to <code class="computeroutput"><span class="special">.</span><span class="identifier">postcondition</span><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>s</em></span></code><code class="computeroutput"><span class="special">)</span></code> is not a nullary functor, instead it is
|
||
a unary functor taking a variable holding the return value as its one parameter
|
||
<code class="literal"><span class="emphasis"><em>s</em></span></code><code class="computeroutput"><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>result</em></span></code><code class="computeroutput"><span class="special">)</span></code> (this is to properly support subcontracting,
|
||
see <a class="link" href="tutorial.html#boost_contract.tutorial.virtual_public_functions" title="Virtual Public Functions">Virtual
|
||
Public Functions</a> and <a class="link" href="tutorial.html#boost_contract.tutorial.public_function_overrides__subcontracting_" title="Public Function Overrides (Subcontracting)">Public
|
||
Function Overrides</a>).
|
||
</p>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="boost_contract.tutorial.return_values"></a><a class="link" href="tutorial.html#boost_contract.tutorial.return_values" title="Return Values">Return Values</a>
|
||
</h3></div></div></div>
|
||
<p>
|
||
In non-void functions, postconditions might need to access the function return
|
||
value to program assertions. In these cases, programmers are responsible
|
||
to declare a local variable before the contract and to assign it to the return
|
||
value at function exit (when the function does not throw an exception).
|
||
<a href="#ftn.boost_contract.tutorial.return_values.f0" class="footnote" name="boost_contract.tutorial.return_values.f0"><sup class="footnote">[23]</sup></a> For example, for <code class="computeroutput"><a class="link" href="../boost/contract/function.html" title="Function function">boost::contract::function</a></code>
|
||
(similarly for all other contracts):
|
||
</p>
|
||
<pre class="programlisting"><span class="identifier">return_type</span> <span class="identifier">f</span><span class="special">(...)</span> <span class="special">{</span>
|
||
<span class="identifier">return_type</span> <span class="identifier">result</span><span class="special">;</span> <span class="comment">// Must be later assigned to return value.</span>
|
||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">function</span><span class="special">()</span> <span class="comment">// Same for all other contracts.</span>
|
||
<span class="special">...</span>
|
||
<span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">{</span> <span class="comment">// Also capture `result` reference...</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">result</span> <span class="special">==</span> <span class="special">...);</span> <span class="comment">// ...but should not modify captures.</span>
|
||
<span class="special">...</span>
|
||
<span class="special">})</span>
|
||
<span class="special">...</span>
|
||
<span class="special">;</span>
|
||
|
||
<span class="special">...</span>
|
||
<span class="keyword">return</span> <span class="identifier">result</span> <span class="special">=</span> <span class="special">...;</span> <span class="comment">// Assign `result` at each return.</span>
|
||
<span class="special">}</span>
|
||
</pre>
|
||
<p>
|
||
At any point where the enclosing function returns, programmers are responsible
|
||
to assign the result variable to the expression being returned. This can
|
||
be done ensuring that <span class="emphasis"><em>all</em></span> <code class="computeroutput"><span class="keyword">return</span></code>
|
||
statements in the function are of the form:
|
||
</p>
|
||
<pre class="programlisting"><code class="literal"><span class="emphasis"><em>return-type</em></span></code> <span class="identifier">result</span><span class="special">;</span>
|
||
<span class="special">...</span>
|
||
<span class="keyword">return</span> <span class="identifier">result</span> <span class="special">=</span> <code class="literal"><span class="emphasis"><em>return-expression</em></span></code><span class="special">;</span> <span class="comment">// Assign `result` at each return.</span>
|
||
</pre>
|
||
<p>
|
||
The functor used to program postconditions should capture the result variable
|
||
by reference and not by value (because postconditions must access the value
|
||
the result variable will have at function exit, and not the value the result
|
||
variable had when the postcondition functor was first declared). The return
|
||
value should never be used in preconditions, old value copies, or exception
|
||
guarantees (because the return value is not yet correctly evaluated and set
|
||
when preconditions are checked, old values are copied, or if the function
|
||
throws an exception). In any case, programmers should not modify the result
|
||
variable in the contract assertions (see <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.constant_correctness" title="Constant-Correctness">Constant-Correctness</a>).
|
||
</p>
|
||
<p>
|
||
It is also possible to declared the result variable using <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span></code>
|
||
when the function return type does not have a default constructor, or if
|
||
the default constructor is too expensive or undesirable to execute when first
|
||
declaring the result variable (see <a class="link" href="advanced.html#boost_contract.advanced.optional_return_values" title="Optional Return Values">Optional
|
||
Return Values</a>).
|
||
</p>
|
||
<p>
|
||
Non-void virtual public functions and non-void public function overrides
|
||
must always declare and use a result variable even when postconditions do
|
||
not directly use the function return value (this is to properly support subcontracting,
|
||
see <a class="link" href="tutorial.html#boost_contract.tutorial.virtual_public_functions" title="Virtual Public Functions">Virtual
|
||
Public Functions</a> and <a class="link" href="tutorial.html#boost_contract.tutorial.public_function_overrides__subcontracting_" title="Public Function Overrides (Subcontracting)">Public
|
||
Function Overrides</a>).
|
||
</p>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="boost_contract.tutorial.old_values"></a><a class="link" href="tutorial.html#boost_contract.tutorial.old_values" title="Old Values">Old Values</a>
|
||
</h3></div></div></div>
|
||
<p>
|
||
When old values are used in postconditions or in exception guarantees, programmes
|
||
are responsible to declare local variables before the contract and to assign
|
||
them to related old value expressions using <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OLDOF.html" title="Macro BOOST_CONTRACT_OLDOF">BOOST_CONTRACT_OLDOF</a></code>.
|
||
<a href="#ftn.boost_contract.tutorial.old_values.f0" class="footnote" name="boost_contract.tutorial.old_values.f0"><sup class="footnote">[24]</sup></a> For example, for <code class="computeroutput"><a class="link" href="../boost/contract/function.html" title="Function function">boost::contract::function</a></code>
|
||
(similarly for all other contracts):
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">f</span><span class="special">(...)</span> <span class="special">{</span>
|
||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_ptr</span><span class="special"><</span><span class="identifier">old_type</span><span class="special">></span> <span class="identifier">old_var</span> <span class="special">=</span> <span class="identifier">BOOST_CONTRACT_OLDOF</span><span class="special">(</span><span class="identifier">old_expr</span><span class="special">);</span>
|
||
<span class="special">...</span> <span class="comment">// More old value declarations here if needed.</span>
|
||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">function</span><span class="special">()</span> <span class="comment">// Same for all other contracts.</span>
|
||
<span class="special">...</span> <span class="comment">// Preconditions shall not use old values.</span>
|
||
<span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">{</span> <span class="comment">// Capture by reference...</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(*</span><span class="identifier">old_var</span> <span class="special">==</span> <span class="special">...);</span> <span class="comment">// ...but should not modify captures.</span>
|
||
<span class="special">...</span>
|
||
<span class="special">})</span>
|
||
<span class="special">.</span><span class="identifier">except</span><span class="special">([&]</span> <span class="special">{</span> <span class="comment">// Capture by reference...</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">old_var</span><span class="special">->...);</span> <span class="comment">// ...but should not modify captures.</span>
|
||
<span class="special">...</span>
|
||
<span class="special">})</span>
|
||
<span class="special">;</span>
|
||
|
||
<span class="special">...</span>
|
||
<span class="special">}</span>
|
||
</pre>
|
||
<p>
|
||
Old values are handled by this library using the smart pointer class template
|
||
<code class="computeroutput"><a class="link" href="../boost/contract/old_ptr.html" title="Class template old_ptr">boost::contract::old_ptr</a></code>
|
||
(so programmers do not directly manage allocation and deallocation of the
|
||
pointed memory). <a href="#ftn.boost_contract.tutorial.old_values.f1" class="footnote" name="boost_contract.tutorial.old_values.f1"><sup class="footnote">[25]</sup></a> The pointed old value type is automatically qualified as <code class="computeroutput"><span class="keyword">const</span></code> (so old values cannot be mistakenly
|
||
changed by contract assertions, see <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.constant_correctness" title="Constant-Correctness">Constant-Correctness</a>).
|
||
This library ensures that old value pointers are always not null by the time
|
||
postconditions and exception guarantees are checked (so programmers can safely
|
||
dereference and use these pointers in postcondition and exception guarantee
|
||
assertions using <code class="computeroutput"><span class="keyword">operator</span><span class="special">*</span></code>
|
||
and <code class="computeroutput"><span class="keyword">operator</span><span class="special">-></span></code>
|
||
without having to check if old value pointers are not null first).
|
||
</p>
|
||
<p>
|
||
Old values should not be used in preconditions and this library does not
|
||
guarantee that old value pointers are always not null when preconditions
|
||
are checked. <a href="#ftn.boost_contract.tutorial.old_values.f2" class="footnote" name="boost_contract.tutorial.old_values.f2"><sup class="footnote">[26]</sup></a> See <a class="link" href="advanced.html#boost_contract.advanced.old_values_copied_at_body" title="Old Values Copied at Body">Old
|
||
Values Copied at Body</a> for delaying the copy of old values until after
|
||
class invariants (for constructors, destructors, and public functions) and
|
||
preconditions are checked (when necessary, this allows to program old value
|
||
expressions under the simplifying assumption that class invariant and precondition
|
||
assertions are satisfied already).
|
||
</p>
|
||
<p>
|
||
<code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OLDOF.html" title="Macro BOOST_CONTRACT_OLDOF">BOOST_CONTRACT_OLDOF</a></code> is
|
||
a variadic macro and it takes an extra parameter when used in virtual public
|
||
functions or public function overrides (see <a class="link" href="tutorial.html#boost_contract.tutorial.virtual_public_functions" title="Virtual Public Functions">Virtual
|
||
Public Functions</a> and <a class="link" href="tutorial.html#boost_contract.tutorial.public_function_overrides__subcontracting_" title="Public Function Overrides (Subcontracting)">Public
|
||
Function Overrides</a>). C++11 auto declarations can be used with <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OLDOF.html" title="Macro BOOST_CONTRACT_OLDOF">BOOST_CONTRACT_OLDOF</a></code> for brevity
|
||
<code class="computeroutput"><span class="keyword">auto</span> </code><code class="literal">old_<span class="emphasis"><em>variable-name</em></span>
|
||
= BOOST_CONTRACT_OLDOF(<span class="emphasis"><em>expression</em></span>)</code> (but see
|
||
also <a class="link" href="extras.html#boost_contract.extras.old_value_requirements__templates_" title="Old Value Requirements (Templates)">Old
|
||
Value Requirements</a>). See <a class="link" href="extras.html#boost_contract.extras.no_macros__and_no_variadic_macros_" title="No Macros (and No Variadic Macros)">No
|
||
Macros</a> to program old values without using <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OLDOF.html" title="Macro BOOST_CONTRACT_OLDOF">BOOST_CONTRACT_OLDOF</a></code>
|
||
(e.g., on compilers that do not support variadic macros).
|
||
</p>
|
||
<div class="note"><table border="0" summary="Note">
|
||
<tr>
|
||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
|
||
<th align="left">Note</th>
|
||
</tr>
|
||
<tr><td align="left" valign="top"><p>
|
||
This library ensures that old values are copied only once. This library
|
||
also ensures that old values are never copied when postconditions and exception
|
||
guarantees are disabled defining both <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45028039653664.html" title="Macro BOOST_CONTRACT_NO_POSTCONDITIONS">BOOST_CONTRACT_NO_POSTCONDITIONS</a></code>
|
||
and <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_NO_EXCEPTS.html" title="Macro BOOST_CONTRACT_NO_EXCEPTS">BOOST_CONTRACT_NO_EXCEPTS</a></code>
|
||
(note that both these two macros must be defined, defining only <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45028039653664.html" title="Macro BOOST_CONTRACT_NO_POSTCONDITIONS">BOOST_CONTRACT_NO_POSTCONDITIONS</a></code>
|
||
or only <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_NO_EXCEPTS.html" title="Macro BOOST_CONTRACT_NO_EXCEPTS">BOOST_CONTRACT_NO_EXCEPTS</a></code>
|
||
is not sufficient to prevent the run-time cost of old value copies).
|
||
</p></td></tr>
|
||
</table></div>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="boost_contract.tutorial.exception_guarantees"></a><a class="link" href="tutorial.html#boost_contract.tutorial.exception_guarantees" title="Exception Guarantees">Exception
|
||
Guarantees</a>
|
||
</h3></div></div></div>
|
||
<p>
|
||
When exception guarantees are specified, they are programmed using a functor
|
||
<code class="literal"><span class="emphasis"><em>e</em></span></code> passed to <code class="computeroutput"><span class="special">.</span><span class="identifier">except</span><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>e</em></span></code><code class="computeroutput"><span class="special">)</span></code> that can be called with no parameters as
|
||
in <code class="literal"><span class="emphasis"><em>e</em></span></code><code class="computeroutput"><span class="special">()</span></code>.
|
||
Contracts that do not have exception guarantees simply do not call <code class="computeroutput"><span class="special">.</span><span class="identifier">except</span><span class="special">(...)</span></code>. Exception guarantees must appear after
|
||
both preconditions and postconditions when these are all present (see <a class="link" href="tutorial.html#boost_contract.tutorial.preconditions" title="Preconditions">Preconditions</a> and
|
||
<a class="link" href="tutorial.html#boost_contract.tutorial.postconditions" title="Postconditions">Postconditions</a>).
|
||
</p>
|
||
<p>
|
||
C++11 lambda functions are convenient to program exception guarantees, but
|
||
any other nullary functor can be used (see <a class="link" href="extras.html#boost_contract.extras.no_lambda_functions__no_c__11_" title="No Lambda Functions (No C++11)">No
|
||
Lambda Functions</a>). For example, for <code class="computeroutput"><a class="link" href="../boost/contract/function.html" title="Function function">boost::contract::function</a></code>
|
||
(similarly for all other contracts):
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">f</span><span class="special">(...)</span> <span class="special">{</span>
|
||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">function</span><span class="special">()</span> <span class="comment">// Same for all other contracts.</span>
|
||
<span class="special">...</span>
|
||
<span class="special">.</span><span class="identifier">except</span><span class="special">([&]</span> <span class="special">{</span> <span class="comment">// Capture by reference...</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(...);</span> <span class="comment">// ...but should not modify captures.</span>
|
||
<span class="special">...</span>
|
||
<span class="special">})</span>
|
||
<span class="special">;</span>
|
||
|
||
<span class="special">...</span>
|
||
<span class="special">}</span>
|
||
</pre>
|
||
<p>
|
||
The exception guarantee functor should capture all the variables that it
|
||
needs to assert the exception guarantees. In general, these variables should
|
||
be captured by reference and not by value (because exception guarantees need
|
||
to access the value that these variables will have when the function throws,
|
||
and not the value these variables had when the exception guarantee functor
|
||
was first declared). Exception guarantees can also capture old values (see
|
||
<a class="link" href="tutorial.html#boost_contract.tutorial.old_values" title="Old Values">Old Values</a>) but
|
||
they should not access the function return value instead (because the return
|
||
value is not be properly set when the function throws an exception). In any
|
||
case, programmers should not write exception guarantee assertions that modify
|
||
the value of the captured variables, even when those are captured by reference
|
||
(see <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.constant_correctness" title="Constant-Correctness">Constant-Correctness</a>).
|
||
</p>
|
||
<div class="note"><table border="0" summary="Note">
|
||
<tr>
|
||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
|
||
<th align="left">Note</th>
|
||
</tr>
|
||
<tr><td align="left" valign="top"><p>
|
||
In real production code, it might be difficult to program meaningful exception
|
||
guarantees without resorting to expensive old value copies that will slow
|
||
down execution. Therefore, the authors recognize that exception guarantees,
|
||
even if supported by this library, might not be used often in practice
|
||
(and they are not used in most of the examples listed in the rest of this
|
||
documentation). In any case, these performance considerations are ultimately
|
||
left to programmers and their specific application domains.
|
||
</p></td></tr>
|
||
</table></div>
|
||
<p>
|
||
Any code can be programmed in the exception guarantee functor, but it is
|
||
recommended to keep this code simple using mainly assertions and if-statements
|
||
(to avoid programming complex exception guarantees that might be buggy and
|
||
slow to check at run-time). It is also recommended to use <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_ASSERT.html" title="Macro BOOST_CONTRACT_ASSERT">BOOST_CONTRACT_ASSERT</a></code>
|
||
to program exception guarantee assertions because that enables this library
|
||
to print informative error messages when the asserted conditions are evaluated
|
||
to be false (note that this is not a variadic macro, see <a class="link" href="extras.html#boost_contract.extras.no_macros__and_no_variadic_macros_" title="No Macros (and No Variadic Macros)">No
|
||
Macros</a>):
|
||
</p>
|
||
<pre class="programlisting"><span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><code class="literal"><span class="emphasis"><em>boolean-condition</em></span></code><span class="special">)</span>
|
||
<span class="comment">// Or, if `boolean-condition` has commas `,` not already within parenthesis `()`...</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">((</span><code class="literal"><span class="emphasis"><em>boolean-condition</em></span></code><span class="special">))</span> <span class="comment">// ...use extra parenthesis (not a variadic macro).</span>
|
||
</pre>
|
||
<p>
|
||
This library will automatically call the failure handler <code class="computeroutput"><a class="link" href="../boost/contract/except_failure.html" title="Function except_failure">boost::contract::except_failure</a></code>
|
||
if any of the <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_ASSERT.html" title="Macro BOOST_CONTRACT_ASSERT">BOOST_CONTRACT_ASSERT</a></code>
|
||
conditions are false or, more in general, if calling the functor specified
|
||
via <code class="computeroutput"><span class="special">.</span><span class="identifier">except</span><span class="special">(...)</span></code> throws any exception. By default, this
|
||
failure handler prints an error message to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cerr</span></code>
|
||
and terminates the program calling <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">terminate</span></code>
|
||
(see <a class="link" href="advanced.html#boost_contract.advanced.throw_on_failures__and__noexcept__" title="Throw on Failures (and noexcept)">Throw
|
||
on Failures</a> to change the failure handler to exit the program with
|
||
an error code or to take some other custom action).
|
||
</p>
|
||
<div class="note"><table border="0" summary="Note">
|
||
<tr>
|
||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
|
||
<th align="left">Note</th>
|
||
</tr>
|
||
<tr><td align="left" valign="top"><p>
|
||
While it is technically possible for programmers to specify an exception
|
||
guarantee handler that throws an exception in case of an exception guarantee
|
||
failure, this will force C++ to terminate the program. That is because
|
||
the handler will throw an exception while there is already an active exception
|
||
on the stack (the exception thrown by the function body that caused the
|
||
exception guarantees to be checked in the first place). Therefore, programmers
|
||
should not change the exception guarantee failure handler to throw exceptions.
|
||
</p></td></tr>
|
||
</table></div>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="boost_contract.tutorial.class_invariants"></a><a class="link" href="tutorial.html#boost_contract.tutorial.class_invariants" title="Class Invariants">Class Invariants</a>
|
||
</h3></div></div></div>
|
||
<p>
|
||
Public member functions, constructors, and destructors can be programmed
|
||
to also check class invariants. When class invariants are specified, they
|
||
are programmed in a public <code class="computeroutput"><span class="keyword">const</span></code>
|
||
function named <code class="computeroutput"><span class="identifier">invariant</span></code>
|
||
taking no argument and returning <code class="computeroutput"><span class="keyword">void</span></code>.
|
||
Classes that do not have invariants, simply do not declare the <code class="computeroutput"><span class="identifier">invariant</span></code> function. <a href="#ftn.boost_contract.tutorial.class_invariants.f0" class="footnote" name="boost_contract.tutorial.class_invariants.f0"><sup class="footnote">[27]</sup></a> For example:
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">u</span> <span class="special">{</span>
|
||
<span class="keyword">public</span><span class="special">:</span> <span class="comment">// Must be public.</span>
|
||
<span class="keyword">void</span> <span class="identifier">invariant</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="comment">// Must be const.</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(...);</span>
|
||
<span class="special">...</span>
|
||
<span class="special">}</span>
|
||
|
||
<span class="special">...</span>
|
||
<span class="special">};</span>
|
||
</pre>
|
||
<p>
|
||
This member function must be <code class="computeroutput"><span class="keyword">const</span></code>
|
||
because contracts should not modify the object state (see <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.constant_correctness" title="Constant-Correctness">Constant-Correctness</a>).
|
||
This library will generate a compile-time error if the <code class="computeroutput"><span class="keyword">const</span></code>
|
||
qualifier is missing (unless <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_PERMISSIVE.html" title="Macro BOOST_CONTRACT_PERMISSIVE">BOOST_CONTRACT_PERMISSIVE</a></code>
|
||
is defined).
|
||
</p>
|
||
<p>
|
||
Any code can be programmed in the <code class="computeroutput"><span class="identifier">invariant</span></code>
|
||
function, but it is recommended to keep this code simple using mainly assertions
|
||
and if-statements (to avoid programming complex invariants that might be
|
||
buggy and slow to check at run-time). It is also recommended to use <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_ASSERT.html" title="Macro BOOST_CONTRACT_ASSERT">BOOST_CONTRACT_ASSERT</a></code> to program
|
||
class invariant assertions because that enables this library to print informative
|
||
error messages when the asserted conditions are evaluated to be false (note
|
||
that this is not a variadic macro, see <a class="link" href="extras.html#boost_contract.extras.no_macros__and_no_variadic_macros_" title="No Macros (and No Variadic Macros)">No
|
||
Macros</a>):
|
||
</p>
|
||
<pre class="programlisting"><span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><code class="literal"><span class="emphasis"><em>boolean-condition</em></span></code><span class="special">)</span>
|
||
<span class="comment">// Or, if `boolean-condition` has commas `,` not already within parenthesis `()`...</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">((</span><code class="literal"><span class="emphasis"><em>boolean-condition</em></span></code><span class="special">))</span> <span class="comment">// ...use extra parenthesis (not a variadic macro).</span>
|
||
</pre>
|
||
<p>
|
||
This library will automatically call failure handlers <code class="computeroutput"><a class="link" href="../boost/contract/entry_invariant_failure.html" title="Function entry_invariant_failure">boost::contract::entry_invariant_failure</a></code>
|
||
or <code class="computeroutput"><a class="link" href="../boost/contract/exit_invariant_failure.html" title="Function exit_invariant_failure">boost::contract::exit_invariant_failure</a></code>
|
||
if any of the <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_ASSERT.html" title="Macro BOOST_CONTRACT_ASSERT">BOOST_CONTRACT_ASSERT</a></code>
|
||
conditions are false or, more in general, if the <code class="computeroutput"><span class="identifier">invariant</span></code>
|
||
function throws an exception when invariants are checked at function entry
|
||
or exit respectively. By default, these handlers print an error message to
|
||
<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cerr</span></code> and terminate the program calling
|
||
<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">terminate</span></code> (see <a class="link" href="advanced.html#boost_contract.advanced.throw_on_failures__and__noexcept__" title="Throw on Failures (and noexcept)">Throw
|
||
on Failures</a> to change these failure handlers to throw exceptions,
|
||
exit the program with an error code, etc.).
|
||
</p>
|
||
<p>
|
||
See <a class="link" href="advanced.html#boost_contract.advanced.access_specifiers" title="Access Specifiers">Access Specifiers</a>
|
||
to avoid making the <code class="computeroutput"><span class="identifier">invariant</span></code>
|
||
member function <code class="computeroutput"><span class="keyword">public</span></code>. <a href="#ftn.boost_contract.tutorial.class_invariants.f1" class="footnote" name="boost_contract.tutorial.class_invariants.f1"><sup class="footnote">[28]</sup></a> See <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45028039722128.html" title="Macro BOOST_CONTRACT_INVARIANT_FUNC">BOOST_CONTRACT_INVARIANT_FUNC</a></code>
|
||
to use a name different from <code class="computeroutput"><span class="identifier">invariant</span></code>
|
||
(e.g., because <code class="computeroutput"><span class="identifier">invariant</span></code>
|
||
clashes with other names in user-defined classes).
|
||
</p>
|
||
<div class="note"><table border="0" summary="Note">
|
||
<tr>
|
||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
|
||
<th align="left">Note</th>
|
||
</tr>
|
||
<tr><td align="left" valign="top"><p>
|
||
Contract assertions are not checked (not even class invariants) when data
|
||
members are accessed directly (this is different from Eiffel where even
|
||
accessing public data members checks class invariants). Therefore, it might
|
||
be best for both <code class="computeroutput"><span class="keyword">class</span></code>es and
|
||
<code class="computeroutput"><span class="keyword">struct</span></code>s (and also <code class="computeroutput"><span class="keyword">union</span></code>s, see <a class="link" href="extras.html#boost_contract.extras.unions" title="Unions">Unions</a>)
|
||
that have invariants to have no mutable public data members and to access
|
||
data members publicly only via appropriate public functions (e.g., setters
|
||
and getters) that can be programmed to check the class invariants using
|
||
this library.
|
||
</p></td></tr>
|
||
</table></div>
|
||
<p>
|
||
See <a class="link" href="extras.html#boost_contract.extras.volatile_public_functions" title="Volatile Public Functions">Volatile
|
||
Public Functions</a> to program invariants for classes with <code class="computeroutput"><span class="keyword">volatile</span></code> public functions.
|
||
</p>
|
||
<h5>
|
||
<a name="boost_contract.tutorial.class_invariants.h0"></a>
|
||
<span class="phrase"><a name="boost_contract.tutorial.class_invariants.static_class_invariants"></a></span><a class="link" href="tutorial.html#boost_contract.tutorial.class_invariants.static_class_invariants">Static
|
||
Class Invariants</a>
|
||
</h5>
|
||
<p>
|
||
Static public functions can be programmed to check static class invariants.
|
||
When static class invariants are specified, they are programmed in a public
|
||
<code class="computeroutput"><span class="keyword">static</span></code> function named <code class="computeroutput"><span class="identifier">static_invariant</span></code> taking no argument and
|
||
returning <code class="computeroutput"><span class="keyword">void</span></code>. Classes that
|
||
do not have static class invariants, simply do not declare the <code class="computeroutput"><span class="identifier">static_invariant</span></code> function. <a href="#ftn.boost_contract.tutorial.class_invariants.f2" class="footnote" name="boost_contract.tutorial.class_invariants.f2"><sup class="footnote">[29]</sup></a> For example:
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">u</span> <span class="special">{</span>
|
||
<span class="keyword">public</span><span class="special">:</span> <span class="comment">// Must be public.</span>
|
||
<span class="keyword">static</span> <span class="keyword">void</span> <span class="identifier">static_invariant</span><span class="special">()</span> <span class="special">{</span> <span class="comment">// Must be static.</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(...);</span>
|
||
<span class="special">...</span>
|
||
<span class="special">}</span>
|
||
|
||
<span class="special">...</span>
|
||
<span class="special">};</span>
|
||
</pre>
|
||
<p>
|
||
This member function must be <code class="computeroutput"><span class="keyword">static</span></code>
|
||
(and it correctly cannot access the object <code class="computeroutput"><span class="keyword">this</span></code>).
|
||
This library will generate a compile-time error if the <code class="computeroutput"><span class="keyword">static</span></code>
|
||
classifier is missing (unless the <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_PERMISSIVE.html" title="Macro BOOST_CONTRACT_PERMISSIVE">BOOST_CONTRACT_PERMISSIVE</a></code>
|
||
macro is defined).
|
||
</p>
|
||
<p>
|
||
Any code can be programmed in the <code class="computeroutput"><span class="identifier">static_invariant</span></code>
|
||
function, but it is recommended to keep this code simple using mainly assertions
|
||
and if-statements (to avoid programming complex static invariants that might
|
||
be buggy and slow to check at run-time). It is also recommended to use <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_ASSERT.html" title="Macro BOOST_CONTRACT_ASSERT">BOOST_CONTRACT_ASSERT</a></code> to program
|
||
the assertions because that enables this library to print informative error
|
||
messages when the asserted conditions are evaluated to be false (note that
|
||
this is not a variadic macro, see <a class="link" href="extras.html#boost_contract.extras.no_macros__and_no_variadic_macros_" title="No Macros (and No Variadic Macros)">No
|
||
Macros</a>):
|
||
</p>
|
||
<pre class="programlisting"><span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><code class="literal"><span class="emphasis"><em>boolean-condition</em></span></code><span class="special">)</span>
|
||
<span class="comment">// Or, if `boolean-condition` has commas `,` not already within parenthesis `()`...</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">((</span><code class="literal"><span class="emphasis"><em>boolean-condition</em></span></code><span class="special">))</span> <span class="comment">// ...use extra parenthesis (not a variadic macro).</span>
|
||
</pre>
|
||
<p>
|
||
This library will automatically call failure handlers <code class="computeroutput"><a class="link" href="../boost/contract/entry_invariant_failure.html" title="Function entry_invariant_failure">boost::contract::entry_invariant_failure</a></code>
|
||
or <code class="computeroutput"><a class="link" href="../boost/contract/exit_invariant_failure.html" title="Function exit_invariant_failure">boost::contract::exit_invariant_failure</a></code>
|
||
if any of the <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_ASSERT.html" title="Macro BOOST_CONTRACT_ASSERT">BOOST_CONTRACT_ASSERT</a></code>
|
||
conditions are false or, more in general, if the <code class="computeroutput"><span class="identifier">static_invariant</span></code>
|
||
function throws an exception when invariants are checked at function entry
|
||
or exit respectively. By default, these handlers print an error message to
|
||
<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cerr</span></code> and terminate the program calling
|
||
<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">terminate</span></code> (see <a class="link" href="advanced.html#boost_contract.advanced.throw_on_failures__and__noexcept__" title="Throw on Failures (and noexcept)">Throw
|
||
on Failures</a> to change these failure handlers to throw exceptions,
|
||
exit the program with an error code, etc.).
|
||
</p>
|
||
<p>
|
||
See <a class="link" href="advanced.html#boost_contract.advanced.access_specifiers" title="Access Specifiers">Access Specifiers</a>
|
||
to avoid making <code class="computeroutput"><span class="identifier">static_invariant</span></code>
|
||
member function <code class="computeroutput"><span class="keyword">public</span></code>. <a href="#ftn.boost_contract.tutorial.class_invariants.f3" class="footnote" name="boost_contract.tutorial.class_invariants.f3"><sup class="footnote">[30]</sup></a> See <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45028039712400.html" title="Macro BOOST_CONTRACT_STATIC_INVARIANT_FUNC">BOOST_CONTRACT_STATIC_INVARIANT_FUNC</a></code>
|
||
to use a name different from <code class="computeroutput"><span class="identifier">static_invariant</span></code>
|
||
(e.g., because <code class="computeroutput"><span class="identifier">static_invariant</span></code>
|
||
clashes with other names in user-defined classes). <a href="#ftn.boost_contract.tutorial.class_invariants.f4" class="footnote" name="boost_contract.tutorial.class_invariants.f4"><sup class="footnote">[31]</sup></a>
|
||
</p>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="boost_contract.tutorial.constructors"></a><a class="link" href="tutorial.html#boost_contract.tutorial.constructors" title="Constructors">Constructors</a>
|
||
</h3></div></div></div>
|
||
<p>
|
||
Contracts for constructors are programmed using the <code class="computeroutput"><a class="link" href="../boost/contract/constructor.html" title="Function template constructor">boost::contract::constructor</a></code>
|
||
function and the <code class="computeroutput"><a class="link" href="../boost/contract/constructor_precondition.html" title="Class template constructor_precondition">boost::contract::constructor_precondition</a></code>
|
||
base class. For example (see <a href="../../../example/features/public.cpp" target="_top"><code class="literal">public.cpp</code></a>):
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">unique_identifiers</span> <span class="special">:</span>
|
||
<span class="keyword">private</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">constructor_precondition</span><span class="special"><</span><span class="identifier">unique_identifiers</span><span class="special">></span>
|
||
<span class="special">{</span>
|
||
<span class="keyword">public</span><span class="special">:</span>
|
||
<span class="keyword">void</span> <span class="identifier">invariant</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special">>=</span> <span class="number">0</span><span class="special">);</span>
|
||
<span class="special">}</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">public</span><span class="special">:</span>
|
||
<span class="comment">// Contract for a constructor.</span>
|
||
<span class="identifier">unique_identifiers</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">from</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">to</span><span class="special">)</span> <span class="special">:</span>
|
||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">constructor_precondition</span><span class="special"><</span><span class="identifier">unique_identifiers</span><span class="special">>([&]</span> <span class="special">{</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">from</span> <span class="special">>=</span> <span class="number">0</span><span class="special">);</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">to</span> <span class="special">>=</span> <span class="identifier">from</span><span class="special">);</span>
|
||
<span class="special">})</span>
|
||
<span class="special">{</span>
|
||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">constructor</span><span class="special">(</span><span class="keyword">this</span><span class="special">)</span>
|
||
<span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">{</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="special">(</span><span class="identifier">to</span> <span class="special">-</span> <span class="identifier">from</span> <span class="special">+</span> <span class="number">1</span><span class="special">));</span>
|
||
<span class="special">})</span>
|
||
<span class="special">;</span>
|
||
|
||
<span class="comment">// Constructor body.</span>
|
||
<span class="keyword">for</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">id</span> <span class="special">=</span> <span class="identifier">from</span><span class="special">;</span> <span class="identifier">id</span> <span class="special"><=</span> <span class="identifier">to</span><span class="special">;</span> <span class="special">++</span><span class="identifier">id</span><span class="special">)</span> <span class="identifier">vect_</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">id</span><span class="special">);</span>
|
||
<span class="special">}</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"> <span class="comment">/* ... */</span>
|
||
<span class="special">};</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
It is not possible to specify preconditions using <code class="computeroutput"><span class="special">.</span><span class="identifier">precondition</span><span class="special">(...)</span></code>
|
||
for constructors (this library will generate a compile-time error if <code class="computeroutput"><span class="special">.</span><span class="identifier">precondition</span><span class="special">(...)</span></code> is used on the object returned by <code class="computeroutput"><a class="link" href="../boost/contract/constructor.html" title="Function template constructor">boost::contract::constructor</a></code>).
|
||
Constructor preconditions are specified using the <code class="computeroutput"><a class="link" href="../boost/contract/constructor_precondition.html" title="Class template constructor_precondition">boost::contract::constructor_precondition</a></code>
|
||
base class instead (same considerations as the ones made in <a class="link" href="tutorial.html#boost_contract.tutorial.preconditions" title="Preconditions">Preconditions</a>
|
||
apply also to the precondition functor passed to <code class="computeroutput"><a class="link" href="../boost/contract/constructor_precondition.html" title="Class template constructor_precondition">boost::contract::constructor_precondition</a></code>).
|
||
Programmes should not access the object <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> from constructor preconditions (because
|
||
the object does not exists yet before the constructor body is executed).
|
||
<a href="#ftn.boost_contract.tutorial.constructors.f0" class="footnote" name="boost_contract.tutorial.constructors.f0"><sup class="footnote">[32]</sup></a> Constructors without preconditions simply do not explicitly initialize
|
||
the <code class="computeroutput"><a class="link" href="../boost/contract/constructor_precondition.html" title="Class template constructor_precondition">boost::contract::constructor_precondition</a></code>
|
||
base (because <code class="computeroutput"><a class="link" href="../boost/contract/constructor_precondition.html" title="Class template constructor_precondition">boost::contract::constructor_precondition</a></code>
|
||
default constructor checks no contract). When the <code class="computeroutput"><a class="link" href="../boost/contract/constructor_precondition.html" title="Class template constructor_precondition">boost::contract::constructor_precondition</a></code>
|
||
base class is used: <a href="#ftn.boost_contract.tutorial.constructors.f1" class="footnote" name="boost_contract.tutorial.constructors.f1"><sup class="footnote">[33]</sup></a>
|
||
</p>
|
||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||
<li class="listitem">
|
||
It should be specified as the <span class="emphasis"><em>first</em></span> class in the
|
||
inheritance list (so constructor preconditions are checked before initializing
|
||
any other base class or data member).
|
||
</li>
|
||
<li class="listitem">
|
||
Its inheritance access specifier should always be <code class="computeroutput"><span class="keyword">private</span></code>
|
||
(so this extra base class does not alter the public inheritance tree
|
||
of its derived classes).
|
||
</li>
|
||
<li class="listitem">
|
||
It should never be declared as a <code class="computeroutput"><span class="keyword">virtual</span></code>
|
||
base (because virtual bases are initialized only once across the entire
|
||
inheritance hierarchy preventing preconditions of other base classes
|
||
from being checked).
|
||
</li>
|
||
<li class="listitem">
|
||
It takes the derived class as template parameter. <a href="#ftn.boost_contract.tutorial.constructors.f2" class="footnote" name="boost_contract.tutorial.constructors.f2"><sup class="footnote">[34]</sup></a>
|
||
</li>
|
||
</ul></div>
|
||
<div class="note"><table border="0" summary="Note">
|
||
<tr>
|
||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
|
||
<th align="left">Note</th>
|
||
</tr>
|
||
<tr><td align="left" valign="top"><p>
|
||
A class can avoid inheriting from <code class="computeroutput"><a class="link" href="../boost/contract/constructor_precondition.html" title="Class template constructor_precondition">boost::contract::constructor_precondition</a></code>
|
||
for efficiency but only when all its constructors have no preconditions.
|
||
</p></td></tr>
|
||
</table></div>
|
||
<p>
|
||
It is possible to specify postconditions for constructors (see <a class="link" href="tutorial.html#boost_contract.tutorial.postconditions" title="Postconditions">Postconditions</a>),
|
||
but programmers should not access the old value of the object <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> in constructor
|
||
postconditions (because the object did not exist yet before the constructor
|
||
body was executed). <a href="#ftn.boost_contract.tutorial.constructors.f3" class="footnote" name="boost_contract.tutorial.constructors.f3"><sup class="footnote">[35]</sup></a> It is also possible to specify exceptions guarantees for constructors
|
||
(see <a class="link" href="tutorial.html#boost_contract.tutorial.exception_guarantees" title="Exception Guarantees">Exception
|
||
Guarantees</a>), but programmers should not access the object <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> or its
|
||
old value in constructor exception guarantees (because the object did not
|
||
exist before executing the constructor body and it was not properly constructed
|
||
given the constructor body threw an exception). <a href="#ftn.boost_contract.tutorial.constructors.f4" class="footnote" name="boost_contract.tutorial.constructors.f4"><sup class="footnote">[36]</sup></a> The <code class="computeroutput"><a class="link" href="../boost/contract/constructor.html" title="Function template constructor">boost::contract::constructor</a></code>
|
||
function takes <code class="computeroutput"><span class="keyword">this</span></code> as a parameter
|
||
(because constructors check class invariants, see <a class="link" href="tutorial.html#boost_contract.tutorial.class_invariants" title="Class Invariants">Class
|
||
Invariants</a>).
|
||
</p>
|
||
<p>
|
||
The <code class="computeroutput"><a class="link" href="../boost/contract/constructor.html" title="Function template constructor">boost::contract::constructor</a></code>
|
||
function returns an RAII object that must always be assigned to a local variable
|
||
of type <code class="computeroutput"><a class="link" href="../boost/contract/check.html" title="Class check">boost::contract::check</a></code>
|
||
(otherwise this library will generate a run-time error, see <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45028039691696.html" title="Macro BOOST_CONTRACT_ON_MISSING_CHECK_DECL">BOOST_CONTRACT_ON_MISSING_CHECK_DECL</a></code>).
|
||
Furthermore, C++11 <code class="computeroutput"><span class="keyword">auto</span></code> declarations
|
||
cannot be used here and the <code class="computeroutput"><a class="link" href="../boost/contract/check.html" title="Class check">boost::contract::check</a></code>
|
||
type must be explicitly specified (otherwise this library will generate a
|
||
compile-time error prior C++17 and a run-time error post C++17). The constructor
|
||
body is programmed right after the declaration of this RAII object.
|
||
</p>
|
||
<p>
|
||
At construction, the <code class="computeroutput"><a class="link" href="../boost/contract/check.html" title="Class check">boost::contract::check</a></code>
|
||
RAII object for constructors does the following (enclosing constructor entry):
|
||
</p>
|
||
<div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">
|
||
Check static class invariants, by calling <code class="literal"><span class="emphasis"><em>type-of</em></span></code><code class="computeroutput"><span class="special">(*</span><span class="keyword">this</span><span class="special">)::</span><span class="identifier">static_invariant</span><span class="special">()</span></code> (but not non-static class invariants
|
||
because the object does not exist yet).
|
||
</li></ol></div>
|
||
<p>
|
||
At destruction instead (enclosing constructor exit):
|
||
</p>
|
||
<div class="orderedlist"><ol class="orderedlist" type="1">
|
||
<li class="listitem">
|
||
Check static class invariants, by calling <code class="literal"><span class="emphasis"><em>type-of</em></span></code><code class="computeroutput"><span class="special">(*</span><span class="keyword">this</span><span class="special">)::</span><span class="identifier">static_invariant</span><span class="special">()</span></code>.
|
||
</li>
|
||
<li class="listitem">
|
||
If the constructor body did not throw an exception:
|
||
<div class="orderedlist"><ol class="orderedlist" type="a">
|
||
<li class="listitem">
|
||
Check non-static class invariants, by calling <code class="computeroutput"><span class="keyword">this</span><span class="special">-></span><span class="identifier">invariant</span><span class="special">()</span></code>.
|
||
</li>
|
||
<li class="listitem">
|
||
Check postconditions, by calling the nullary functor <code class="literal"><span class="emphasis"><em>s</em></span></code><code class="computeroutput"><span class="special">()</span></code> passed to <code class="computeroutput"><span class="special">.</span><span class="identifier">postcondition</span><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>s</em></span></code><code class="computeroutput"><span class="special">)</span></code>.
|
||
</li>
|
||
</ol></div>
|
||
</li>
|
||
<li class="listitem">
|
||
Else:
|
||
<div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem">
|
||
Check exception guarantees, by calling the nullary functor <code class="literal"><span class="emphasis"><em>e</em></span></code><code class="computeroutput"><span class="special">()</span></code> passed to <code class="computeroutput"><span class="special">.</span><span class="identifier">except</span><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>e</em></span></code><code class="computeroutput"><span class="special">)</span></code>.
|
||
</li></ol></div>
|
||
</li>
|
||
</ol></div>
|
||
<p>
|
||
This together with C++ object construction mechanism of base classes and
|
||
the use of <code class="computeroutput"><a class="link" href="../boost/contract/constructor_precondition.html" title="Class template constructor_precondition">boost::contract::constructor_precondition</a></code>
|
||
ensures that the constructor contracts are correctly checked at run-time
|
||
(see <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.constructor_calls" title="Constructor Calls">Constructor
|
||
Calls</a>).
|
||
</p>
|
||
<div class="note"><table border="0" summary="Note">
|
||
<tr>
|
||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
|
||
<th align="left">Note</th>
|
||
</tr>
|
||
<tr><td align="left" valign="top">
|
||
<p>
|
||
A constructor can avoid calling <code class="computeroutput"><a class="link" href="../boost/contract/constructor.html" title="Function template constructor">boost::contract::constructor</a></code>
|
||
for efficiency but only when it has no postconditions, no exception guarantees,
|
||
and its class has no invariants (even if <code class="computeroutput"><a class="link" href="../boost/contract/constructor.html" title="Function template constructor">boost::contract::constructor</a></code>
|
||
is not used by a derived class, contracts of base class constructors will
|
||
still be correctly checked by C++ object construction mechanism).
|
||
</p>
|
||
<p>
|
||
The default constructor and copy constructor automatically generated by
|
||
C++ will not check contracts. Therefore, unless these constructors are
|
||
not public or they have no preconditions, no postconditions, no exception
|
||
guarantees, and their class has no invariants, programmers should manually
|
||
define them using <code class="computeroutput"><a class="link" href="../boost/contract/constructor.html" title="Function template constructor">boost::contract::constructor</a></code>
|
||
and <code class="computeroutput"><a class="link" href="../boost/contract/constructor_precondition.html" title="Class template constructor_precondition">boost::contract::constructor_precondition</a></code>.
|
||
Similar considerations apply to all other constructors automatically generated
|
||
by C++ (e.g., the move constructor).
|
||
</p>
|
||
</td></tr>
|
||
</table></div>
|
||
<h5>
|
||
<a name="boost_contract.tutorial.constructors.h0"></a>
|
||
<span class="phrase"><a name="boost_contract.tutorial.constructors.private_and_protected_constructors"></a></span><a class="link" href="tutorial.html#boost_contract.tutorial.constructors.private_and_protected_constructors">Private
|
||
and Protected Constructors</a>
|
||
</h5>
|
||
<p>
|
||
Private and protected constructors can omit <code class="computeroutput"><a class="link" href="../boost/contract/constructor.html" title="Function template constructor">boost::contract::constructor</a></code>
|
||
(because they are not part of the public interface of the class so they are
|
||
not required to check class invariants, see <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.constructor_calls" title="Constructor Calls">Constructor
|
||
Calls</a>). They could still use <code class="computeroutput"><a class="link" href="../boost/contract/constructor_precondition.html" title="Class template constructor_precondition">boost::contract::constructor_precondition</a></code>
|
||
to check preconditions before member initializations, and even use <code class="computeroutput"><a class="link" href="../boost/contract/function.html" title="Function function">boost::contract::function</a></code>
|
||
(but not <code class="computeroutput"><a class="link" href="../boost/contract/constructor.html" title="Function template constructor">boost::contract::constructor</a></code>)
|
||
to only check postconditions and exception guarantees without checking class
|
||
invariants and without calling <code class="computeroutput"><span class="special">.</span><span class="identifier">precondition</span><span class="special">(...)</span></code>
|
||
(see <a class="link" href="advanced.html#boost_contract.advanced.private_and_protected_functions" title="Private and Protected Functions">Private
|
||
and Protected Functions</a>). For example:
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">u</span> <span class="special">:</span> <span class="keyword">private</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">constructor_precondition</span><span class="special"><</span><span class="identifier">u</span><span class="special">></span> <span class="special">{</span>
|
||
<span class="keyword">protected</span><span class="special">:</span>
|
||
<span class="comment">// Contract for a protected constructor (same for private constructors).</span>
|
||
<span class="identifier">u</span><span class="special">()</span> <span class="special">:</span> <span class="comment">// Still use this base class to check constructor preconditions.</span>
|
||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">constructor_precondition</span><span class="special"><</span><span class="identifier">u</span><span class="special">>([&]</span> <span class="special">{</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(...);</span>
|
||
<span class="special">...</span>
|
||
<span class="special">})</span>
|
||
<span class="special">{</span>
|
||
<span class="comment">// Following will correctly not check class invariants.</span>
|
||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">function</span><span class="special">()</span>
|
||
<span class="comment">// Do not use `.precondition(...)` here.</span>
|
||
<span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">{</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(...);</span>
|
||
<span class="special">...</span>
|
||
<span class="special">})</span>
|
||
<span class="special">.</span><span class="identifier">except</span><span class="special">([&]</span> <span class="special">{</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(...);</span>
|
||
<span class="special">...</span>
|
||
<span class="special">})</span>
|
||
<span class="special">;</span>
|
||
|
||
<span class="special">...</span> <span class="comment">// Constructor body.</span>
|
||
<span class="special">}</span>
|
||
|
||
<span class="special">...</span>
|
||
<span class="special">};</span>
|
||
</pre>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="boost_contract.tutorial.destructors"></a><a class="link" href="tutorial.html#boost_contract.tutorial.destructors" title="Destructors">Destructors</a>
|
||
</h3></div></div></div>
|
||
<p>
|
||
Contracts for destructors are programmed using <code class="computeroutput"><a class="link" href="../boost/contract/destructor.html" title="Function template destructor">boost::contract::destructor</a></code>.
|
||
For example (see <a href="../../../example/features/public.cpp" target="_top"><code class="literal">public.cpp</code></a>):
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">unique_identifiers</span> <span class="special">:</span>
|
||
<span class="keyword">private</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">constructor_precondition</span><span class="special"><</span><span class="identifier">unique_identifiers</span><span class="special">></span>
|
||
<span class="special">{</span>
|
||
<span class="keyword">public</span><span class="special">:</span>
|
||
<span class="keyword">void</span> <span class="identifier">invariant</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special">>=</span> <span class="number">0</span><span class="special">);</span>
|
||
<span class="special">}</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">public</span><span class="special">:</span>
|
||
<span class="comment">// Contract for a destructor.</span>
|
||
<span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">unique_identifiers</span><span class="special">()</span> <span class="special">{</span>
|
||
<span class="comment">// Following contract checks class invariants.</span>
|
||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">destructor</span><span class="special">(</span><span class="keyword">this</span><span class="special">);</span>
|
||
|
||
<span class="comment">// Destructor body here... (do nothing in this example).</span>
|
||
<span class="special">}</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"> <span class="comment">/* ... */</span>
|
||
<span class="special">};</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
It is not possible to specify preconditions for destructors (this library
|
||
will generate a compile-time error if <code class="computeroutput"><span class="special">.</span><span class="identifier">precondition</span><span class="special">(...)</span></code>
|
||
is used here and that is because destructors can be called at any time after
|
||
construction so they have no precondition). It is possible to specify postconditions
|
||
for destructors (see <a class="link" href="tutorial.html#boost_contract.tutorial.postconditions" title="Postconditions">Postconditions</a>,
|
||
and also <a class="link" href="tutorial.html#boost_contract.tutorial.static_public_functions" title="Static Public Functions">Static
|
||
Public Functions</a> for an example), but programmers should not access
|
||
the object <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
|
||
in destructor postconditions (because the object no longer exists after the
|
||
destructor body has been executed). <a href="#ftn.boost_contract.tutorial.destructors.f0" class="footnote" name="boost_contract.tutorial.destructors.f0"><sup class="footnote">[37]</sup></a> It is also possible to specify exceptions guarantees for destructors
|
||
(see <a class="link" href="tutorial.html#boost_contract.tutorial.exception_guarantees" title="Exception Guarantees">Exception
|
||
Guarantees</a>, even if destructors should usually be programmed to not
|
||
throw exceptions in C++, in fact destructors are implicitly declared <code class="computeroutput"><span class="keyword">noexcept</span></code> since C++11). <a href="#ftn.boost_contract.tutorial.destructors.f1" class="footnote" name="boost_contract.tutorial.destructors.f1"><sup class="footnote">[38]</sup></a> The <code class="computeroutput"><a class="link" href="../boost/contract/destructor.html" title="Function template destructor">boost::contract::destructor</a></code>
|
||
function takes <code class="computeroutput"><span class="keyword">this</span></code> as a parameter
|
||
(because destructors check class invariants, see <a class="link" href="tutorial.html#boost_contract.tutorial.class_invariants" title="Class Invariants">Class
|
||
Invariants</a>).
|
||
</p>
|
||
<p>
|
||
The <code class="computeroutput"><a class="link" href="../boost/contract/destructor.html" title="Function template destructor">boost::contract::destructor</a></code>
|
||
function returns an RAII object that must always be assigned to a local variable
|
||
of type <code class="computeroutput"><a class="link" href="../boost/contract/check.html" title="Class check">boost::contract::check</a></code>
|
||
(otherwise this library will generate a run-time error, see <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45028039691696.html" title="Macro BOOST_CONTRACT_ON_MISSING_CHECK_DECL">BOOST_CONTRACT_ON_MISSING_CHECK_DECL</a></code>).
|
||
Furthermore, C++11 <code class="computeroutput"><span class="keyword">auto</span></code> declarations
|
||
cannot be used here and the <code class="computeroutput"><a class="link" href="../boost/contract/check.html" title="Class check">boost::contract::check</a></code>
|
||
type must be explicitly specified (otherwise this library will generate a
|
||
compile-time error prior C++17 and a run-time error post C++17). The destructor
|
||
body is programmed right after the declaration of this RAII object.
|
||
</p>
|
||
<p>
|
||
At construction, the <code class="computeroutput"><a class="link" href="../boost/contract/check.html" title="Class check">boost::contract::check</a></code>
|
||
RAII object for destructors does the following (enclosing destructor entry):
|
||
</p>
|
||
<div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">
|
||
Check static and non-static class invariants, by calling <span class="emphasis"><em><code class="literal">type-of</code></em></span><code class="computeroutput"><span class="special">(*</span><span class="keyword">this</span><span class="special">)::</span><span class="identifier">static_invariant</span><span class="special">()</span></code> <a class="link" href="contract_programming_overview.html#and_anchor"><code class="literal"><span class="emphasis"><em>AND</em></span></code></a>
|
||
<code class="computeroutput"><span class="keyword">this</span><span class="special">-></span><span class="identifier">invariant</span><span class="special">()</span></code>.
|
||
</li></ol></div>
|
||
<p>
|
||
At destruction instead (enclosing destructor exit):
|
||
</p>
|
||
<div class="orderedlist"><ol class="orderedlist" type="1">
|
||
<li class="listitem">
|
||
Check static class invariants, by calling <code class="literal"><span class="emphasis"><em>type-of</em></span></code><code class="computeroutput"><span class="special">(*</span><span class="keyword">this</span><span class="special">)::</span><span class="identifier">static_invariant</span><span class="special">()</span></code>.
|
||
</li>
|
||
<li class="listitem">
|
||
If the destructor body did not throw an exception:
|
||
<div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem">
|
||
Check postconditions, by calling the nullay functor <code class="literal"><span class="emphasis"><em>s</em></span></code><code class="computeroutput"><span class="special">()</span></code> passed to <code class="computeroutput"><span class="special">.</span><span class="identifier">postcondition</span><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>s</em></span></code><code class="computeroutput"><span class="special">)</span></code>.
|
||
</li></ol></div>
|
||
</li>
|
||
<li class="listitem">
|
||
Else (even if destructors should generally be programmed not to throw
|
||
in C++):
|
||
<div class="orderedlist"><ol class="orderedlist" type="a">
|
||
<li class="listitem">
|
||
Check non-static class invariants, by calling <code class="computeroutput"><span class="keyword">this</span><span class="special">-></span><span class="identifier">invariant</span><span class="special">()</span></code> (because the object was not successfully
|
||
destructed).
|
||
</li>
|
||
<li class="listitem">
|
||
Check exception guarantees, by calling the nullary functor <code class="literal"><span class="emphasis"><em>e</em></span></code><code class="computeroutput"><span class="special">()</span></code> passed to <code class="computeroutput"><span class="special">.</span><span class="identifier">except</span><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>e</em></span></code><code class="computeroutput"><span class="special">)</span></code>.
|
||
</li>
|
||
</ol></div>
|
||
</li>
|
||
</ol></div>
|
||
<p>
|
||
This together with C++ object destruction mechanism of base classes ensures
|
||
that destructor contracts are correctly checked at run-time (see <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.destructor_calls" title="Destructor Calls">Destructor
|
||
Calls</a>).
|
||
</p>
|
||
<div class="note"><table border="0" summary="Note">
|
||
<tr>
|
||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
|
||
<th align="left">Note</th>
|
||
</tr>
|
||
<tr><td align="left" valign="top">
|
||
<p>
|
||
A destructor can avoid calling <code class="computeroutput"><a class="link" href="../boost/contract/destructor.html" title="Function template destructor">boost::contract::destructor</a></code>
|
||
for efficiency but only when it has no postconditions, no exception guarantees,
|
||
and its class has no invariants (even if <code class="computeroutput"><a class="link" href="../boost/contract/destructor.html" title="Function template destructor">boost::contract::destructor</a></code>
|
||
is not used by a derived class, contracts of base class destructors will
|
||
still be correctly checked by C++ object destruction mechanism).
|
||
</p>
|
||
<p>
|
||
The default destructor automatically generated by C++ will not check contracts.
|
||
Therefore, unless the destructor is not public or it has no postconditions,
|
||
no exception guarantees, and its class has no invariants, programmers should
|
||
manually define it using <code class="computeroutput"><a class="link" href="../boost/contract/destructor.html" title="Function template destructor">boost::contract::destructor</a></code>.
|
||
</p>
|
||
</td></tr>
|
||
</table></div>
|
||
<h5>
|
||
<a name="boost_contract.tutorial.destructors.h0"></a>
|
||
<span class="phrase"><a name="boost_contract.tutorial.destructors.private_and_protected_destructors"></a></span><a class="link" href="tutorial.html#boost_contract.tutorial.destructors.private_and_protected_destructors">Private
|
||
and Protected Destructors</a>
|
||
</h5>
|
||
<p>
|
||
Private and protected destructors can omit <code class="computeroutput"><a class="link" href="../boost/contract/destructor.html" title="Function template destructor">boost::contract::destructor</a></code>
|
||
(because they are not part of the public interface of the class so they are
|
||
not required to check class invariants, see <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.destructor_calls" title="Destructor Calls">Destructor
|
||
Calls</a>). They could use <code class="computeroutput"><a class="link" href="../boost/contract/function.html" title="Function function">boost::contract::function</a></code>
|
||
(but not <code class="computeroutput"><a class="link" href="../boost/contract/destructor.html" title="Function template destructor">boost::contract::destructor</a></code>)
|
||
to only check postconditions and exception guarantees without checking class
|
||
invariants and without calling <code class="computeroutput"><span class="special">.</span><span class="identifier">precondition</span><span class="special">(...)</span></code>
|
||
(see <a class="link" href="advanced.html#boost_contract.advanced.private_and_protected_functions" title="Private and Protected Functions">Private
|
||
and Protected Functions</a>). For example:
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">u</span> <span class="special">{</span>
|
||
<span class="keyword">protected</span><span class="special">:</span>
|
||
<span class="comment">// Contract for a protected destructor (same for private destructors).</span>
|
||
<span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">u</span><span class="special">()</span> <span class="special">{</span>
|
||
<span class="comment">// Following will correctly not check class invariants.</span>
|
||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">function</span><span class="special">()</span>
|
||
<span class="comment">// Do not use `.precondition(...)` here.</span>
|
||
<span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">{</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(...);</span>
|
||
<span class="special">...</span>
|
||
<span class="special">})</span>
|
||
<span class="comment">// Could use `.except(...)` here in rare cases of destructors declared to throw.</span>
|
||
<span class="special">;</span>
|
||
|
||
<span class="special">...</span> <span class="comment">// Destructor body.</span>
|
||
<span class="special">}</span>
|
||
|
||
<span class="special">...</span>
|
||
<span class="special">};</span>
|
||
</pre>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="boost_contract.tutorial.public_functions"></a><a class="link" href="tutorial.html#boost_contract.tutorial.public_functions" title="Public Functions">Public Functions</a>
|
||
</h3></div></div></div>
|
||
<p>
|
||
Contracts for public functions are programmed using <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45028038882752.html" title="Function template public_function">boost::contract::public_function</a></code>.
|
||
In this section, let's consider public functions that are not static, not
|
||
virtual, and do not override any function from base classes. For example
|
||
(see <a href="../../../example/features/public.cpp" target="_top"><code class="literal">public.cpp</code></a>):
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">unique_identifiers</span> <span class="special">:</span>
|
||
<span class="keyword">private</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">constructor_precondition</span><span class="special"><</span><span class="identifier">unique_identifiers</span><span class="special">></span>
|
||
<span class="special">{</span>
|
||
<span class="keyword">public</span><span class="special">:</span>
|
||
<span class="keyword">void</span> <span class="identifier">invariant</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special">>=</span> <span class="number">0</span><span class="special">);</span>
|
||
<span class="special">}</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">public</span><span class="special">:</span>
|
||
<span class="comment">// Contract for a public function (but no static, virtual, or override).</span>
|
||
<span class="keyword">bool</span> <span class="identifier">find</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">id</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">{</span>
|
||
<span class="keyword">bool</span> <span class="identifier">result</span><span class="special">;</span>
|
||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">public_function</span><span class="special">(</span><span class="keyword">this</span><span class="special">)</span>
|
||
<span class="special">.</span><span class="identifier">precondition</span><span class="special">([&]</span> <span class="special">{</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">id</span> <span class="special">>=</span> <span class="number">0</span><span class="special">);</span>
|
||
<span class="special">})</span>
|
||
<span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">{</span>
|
||
<span class="keyword">if</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">0</span><span class="special">)</span> <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(!</span><span class="identifier">result</span><span class="special">);</span>
|
||
<span class="special">})</span>
|
||
<span class="special">;</span>
|
||
|
||
<span class="comment">// Function body.</span>
|
||
<span class="keyword">return</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">find</span><span class="special">(</span><span class="identifier">vect_</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">vect_</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">id</span><span class="special">)</span> <span class="special">!=</span>
|
||
<span class="identifier">vect_</span><span class="special">.</span><span class="identifier">end</span><span class="special">();</span>
|
||
<span class="special">}</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"> <span class="comment">/* ... */</span>
|
||
<span class="special">};</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
It is possible to specify preconditions, postconditions, and exception guarantees
|
||
for public functions (see <a class="link" href="tutorial.html#boost_contract.tutorial.preconditions" title="Preconditions">Preconditions</a>,
|
||
<a class="link" href="tutorial.html#boost_contract.tutorial.postconditions" title="Postconditions">Postconditions</a>,
|
||
and <a class="link" href="tutorial.html#boost_contract.tutorial.exception_guarantees" title="Exception Guarantees">Exception
|
||
Guarantees</a>). When called from non-static public functions, the <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45028038882752.html" title="Function template public_function">boost::contract::public_function</a></code>
|
||
function takes <code class="computeroutput"><span class="keyword">this</span></code> as a parameter
|
||
(because public functions check class invariants, see <a class="link" href="tutorial.html#boost_contract.tutorial.class_invariants" title="Class Invariants">Class
|
||
Invariants</a>).
|
||
</p>
|
||
<p>
|
||
The <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45028038882752.html" title="Function template public_function">boost::contract::public_function</a></code>
|
||
function returns an RAII object that must always be assigned to a local variable
|
||
of type <code class="computeroutput"><a class="link" href="../boost/contract/check.html" title="Class check">boost::contract::check</a></code>
|
||
(otherwise this library will generate a run-time error, see <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45028039691696.html" title="Macro BOOST_CONTRACT_ON_MISSING_CHECK_DECL">BOOST_CONTRACT_ON_MISSING_CHECK_DECL</a></code>).
|
||
Furthermore, C++11 <code class="computeroutput"><span class="keyword">auto</span></code> declarations
|
||
cannot be used here and the <code class="computeroutput"><a class="link" href="../boost/contract/check.html" title="Class check">boost::contract::check</a></code>
|
||
type must be explicitly specified (otherwise this library will generate a
|
||
compile-time error prior C++17 and a run-time error post C++17). The public
|
||
function body is programmed right after the declaration of this RAII object.
|
||
</p>
|
||
<p>
|
||
At construction, the <code class="computeroutput"><a class="link" href="../boost/contract/check.html" title="Class check">boost::contract::check</a></code>
|
||
RAII object for public functions does the following (enclosing public function
|
||
entry):
|
||
</p>
|
||
<div class="orderedlist"><ol class="orderedlist" type="1">
|
||
<li class="listitem">
|
||
Check static and non-static class invariants, by calling <code class="literal"><span class="emphasis"><em>type-of</em></span></code><code class="computeroutput"><span class="special">(*</span><span class="keyword">this</span><span class="special">)::</span><span class="identifier">static_invariant</span><span class="special">()</span></code> <a class="link" href="contract_programming_overview.html#and_anchor"><code class="literal"><span class="emphasis"><em>AND</em></span></code></a>
|
||
<code class="computeroutput"><span class="keyword">this</span><span class="special">-></span><span class="identifier">invariant</span><span class="special">()</span></code>.
|
||
</li>
|
||
<li class="listitem">
|
||
Check preconditions, by calling the nullary functor <code class="literal"><span class="emphasis"><em>r</em></span></code><code class="computeroutput"><span class="special">()</span></code> passed to <code class="computeroutput"><span class="special">.</span><span class="identifier">precondition</span><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>r</em></span></code><code class="computeroutput"><span class="special">)</span></code>.
|
||
</li>
|
||
</ol></div>
|
||
<p>
|
||
At destruction instead (enclosing public function exit):
|
||
</p>
|
||
<div class="orderedlist"><ol class="orderedlist" type="1">
|
||
<li class="listitem">
|
||
Check static and non-static class invariants, by calling <code class="literal"><span class="emphasis"><em>type-of</em></span></code><code class="computeroutput"><span class="special">(*</span><span class="keyword">this</span><span class="special">)::</span><span class="identifier">static_invariant</span><span class="special">()</span></code> <a class="link" href="contract_programming_overview.html#and_anchor"><code class="literal"><span class="emphasis"><em>AND</em></span></code></a>
|
||
<code class="computeroutput"><span class="keyword">this</span><span class="special">-></span><span class="identifier">invariant</span><span class="special">()</span></code>
|
||
(even if the function body threw an exception).
|
||
</li>
|
||
<li class="listitem">
|
||
If the function body did not throw an exception:
|
||
<div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem">
|
||
Check postconditions, by calling the nullary functor <code class="literal"><span class="emphasis"><em>s</em></span></code><code class="computeroutput"><span class="special">()</span></code> passed to <code class="computeroutput"><span class="special">.</span><span class="identifier">postcondition</span><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>s</em></span></code><code class="computeroutput"><span class="special">)</span></code>.
|
||
</li></ol></div>
|
||
</li>
|
||
<li class="listitem">
|
||
Else:
|
||
<div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem">
|
||
Check exception guarantees, by calling the nullary functor <code class="literal"><span class="emphasis"><em>e</em></span></code><code class="computeroutput"><span class="special">()</span></code> passed to <code class="computeroutput"><span class="special">.</span><span class="identifier">except</span><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>e</em></span></code><code class="computeroutput"><span class="special">)</span></code>.
|
||
</li></ol></div>
|
||
</li>
|
||
</ol></div>
|
||
<p>
|
||
This ensures that public function contracts are correctly checked at run-time
|
||
(see <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.public_function_calls" title="Public Function Calls">Public
|
||
Function Calls</a>).
|
||
</p>
|
||
<div class="note"><table border="0" summary="Note">
|
||
<tr>
|
||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
|
||
<th align="left">Note</th>
|
||
</tr>
|
||
<tr><td align="left" valign="top">
|
||
<p>
|
||
A public function can avoid calling <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45028038882752.html" title="Function template public_function">boost::contract::public_function</a></code>
|
||
for efficiency but only when it has no preconditions, no postconditions,
|
||
no exception guarantees, it is not virtual, it does not override any virtual
|
||
function, and its class has no invariants.
|
||
</p>
|
||
<p>
|
||
The default copy assignment operator automatically generated by C++ will
|
||
not check contracts. Therefore, unless this operator is not public or it
|
||
has no preconditions, no postconditions, no exception guarantees, and its
|
||
class has no invariants, programmers should manually define it using <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45028038882752.html" title="Function template public_function">boost::contract::public_function</a></code>.
|
||
Similar considerations apply to all other operators automatically generated
|
||
by C++ (e.g., the move operator).
|
||
</p>
|
||
</td></tr>
|
||
</table></div>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="boost_contract.tutorial.virtual_public_functions"></a><a class="link" href="tutorial.html#boost_contract.tutorial.virtual_public_functions" title="Virtual Public Functions">Virtual
|
||
Public Functions</a>
|
||
</h3></div></div></div>
|
||
<p>
|
||
Contracts for public functions are programmed using <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45028038882752.html" title="Function template public_function">boost::contract::public_function</a></code>.
|
||
In this section, let's consider public functions that are virtual but that
|
||
do not override any function from base classes. For example (see <a href="../../../example/features/public.cpp" target="_top"><code class="literal">public.cpp</code></a>):
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">unique_identifiers</span> <span class="special">:</span>
|
||
<span class="keyword">private</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">constructor_precondition</span><span class="special"><</span><span class="identifier">unique_identifiers</span><span class="special">></span>
|
||
<span class="special">{</span>
|
||
<span class="keyword">public</span><span class="special">:</span>
|
||
<span class="keyword">void</span> <span class="identifier">invariant</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special">>=</span> <span class="number">0</span><span class="special">);</span>
|
||
<span class="special">}</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">public</span><span class="special">:</span>
|
||
<span class="comment">// Contract for a public virtual function (but no override).</span>
|
||
<span class="keyword">virtual</span> <span class="keyword">int</span> <span class="identifier">push_back</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">id</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">virtual_</span><span class="special">*</span> <span class="identifier">v</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="special">{</span> <span class="comment">// Extra `v`.</span>
|
||
<span class="keyword">int</span> <span class="identifier">result</span><span class="special">;</span>
|
||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_ptr</span><span class="special"><</span><span class="keyword">bool</span><span class="special">></span> <span class="identifier">old_find</span> <span class="special">=</span>
|
||
<span class="identifier">BOOST_CONTRACT_OLDOF</span><span class="special">(</span><span class="identifier">v</span><span class="special">,</span> <span class="identifier">find</span><span class="special">(</span><span class="identifier">id</span><span class="special">));</span> <span class="comment">// Pass `v`.</span>
|
||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_ptr</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">old_size</span> <span class="special">=</span>
|
||
<span class="identifier">BOOST_CONTRACT_OLDOF</span><span class="special">(</span><span class="identifier">v</span><span class="special">,</span> <span class="identifier">size</span><span class="special">());</span> <span class="comment">// Pass `v`.</span>
|
||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">public_function</span><span class="special">(</span>
|
||
<span class="identifier">v</span><span class="special">,</span> <span class="identifier">result</span><span class="special">,</span> <span class="keyword">this</span><span class="special">)</span> <span class="comment">// Pass `v` and `result`.</span>
|
||
<span class="special">.</span><span class="identifier">precondition</span><span class="special">([&]</span> <span class="special">{</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">id</span> <span class="special">>=</span> <span class="number">0</span><span class="special">);</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(!</span><span class="identifier">find</span><span class="special">(</span><span class="identifier">id</span><span class="special">));</span> <span class="comment">// ID cannot be already present.</span>
|
||
<span class="special">})</span>
|
||
<span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">(</span><span class="keyword">int</span> <span class="keyword">const</span> <span class="identifier">result</span><span class="special">)</span> <span class="special">{</span>
|
||
<span class="keyword">if</span><span class="special">(!*</span><span class="identifier">old_find</span><span class="special">)</span> <span class="special">{</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">find</span><span class="special">(</span><span class="identifier">id</span><span class="special">));</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">old_size</span> <span class="special">+</span> <span class="number">1</span><span class="special">);</span>
|
||
<span class="special">}</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">result</span> <span class="special">==</span> <span class="identifier">id</span><span class="special">);</span>
|
||
<span class="special">})</span>
|
||
<span class="special">;</span>
|
||
|
||
<span class="comment">// Function body.</span>
|
||
<span class="identifier">vect_</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">id</span><span class="special">);</span>
|
||
<span class="keyword">return</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">id</span><span class="special">;</span>
|
||
<span class="special">}</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"> <span class="comment">/* ... */</span>
|
||
<span class="special">};</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
Virtual public functions must declare an extra trailing parameter of type
|
||
<code class="computeroutput"><a class="link" href="../boost/contract/virtual_.html" title="Class virtual_">boost::contract::virtual_</a></code><code class="computeroutput"><span class="special">*</span></code> with default value <code class="computeroutput"><span class="number">0</span></code>
|
||
(i.e., <code class="computeroutput"><span class="keyword">nullptr</span></code>). <a href="#ftn.boost_contract.tutorial.virtual_public_functions.f0" class="footnote" name="boost_contract.tutorial.virtual_public_functions.f0"><sup class="footnote">[39]</sup></a> This extra parameter is the last parameter and it has a default
|
||
value so it does not alter the calling interface of the virtual function
|
||
(callers will rarely, if ever, have to explicitly deal with this extra parameter
|
||
a part from when manipulating the virtual function type directly for function
|
||
pointer type-casting, etc.). Programmers must pass the extra virtual parameter
|
||
as the very first argument to all <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OLDOF.html" title="Macro BOOST_CONTRACT_OLDOF">BOOST_CONTRACT_OLDOF</a></code>
|
||
and <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45028038882752.html" title="Function template public_function">boost::contract::public_function</a></code>
|
||
calls in the virtual public function definition. <a href="#ftn.boost_contract.tutorial.virtual_public_functions.f1" class="footnote" name="boost_contract.tutorial.virtual_public_functions.f1"><sup class="footnote">[40]</sup></a>
|
||
</p>
|
||
<p>
|
||
When called from virtual public functions, the <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45028038882752.html" title="Function template public_function">boost::contract::public_function</a></code>
|
||
function takes <code class="computeroutput"><span class="keyword">this</span></code> as a parameter
|
||
(because public functions check class invariants, see <a class="link" href="tutorial.html#boost_contract.tutorial.class_invariants" title="Class Invariants">Class
|
||
Invariants</a>). For virtual public functions returning <code class="computeroutput"><span class="keyword">void</span></code>:
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">u</span> <span class="special">{</span>
|
||
<span class="keyword">public</span><span class="special">:</span>
|
||
<span class="comment">// A void virtual public function (that does not override).</span>
|
||
<span class="keyword">virtual</span> <span class="keyword">void</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">t_1</span> <span class="identifier">a_1</span><span class="special">,</span> <span class="special">...,</span> <span class="identifier">t_n</span> <span class="identifier">a_n</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">virtual_</span><span class="special">*</span> <span class="identifier">v</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="special">{</span>
|
||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">public_function</span><span class="special">(</span>
|
||
<span class="identifier">v</span><span class="special">,</span> <span class="keyword">this</span><span class="special">)</span> <span class="comment">// No result parameter...</span>
|
||
<span class="special">.</span><span class="identifier">precondition</span><span class="special">([&]</span> <span class="special">{</span> <span class="special">...</span> <span class="special">})</span>
|
||
<span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">{</span> <span class="special">...</span> <span class="special">})</span> <span class="comment">// ...so nullary functor.</span>
|
||
<span class="special">.</span><span class="identifier">except</span><span class="special">([&]</span> <span class="special">{</span> <span class="special">...</span> <span class="special">})</span>
|
||
<span class="special">;</span>
|
||
|
||
<span class="special">...</span>
|
||
<span class="special">}</span>
|
||
|
||
<span class="special">...</span>
|
||
<span class="special">}</span>
|
||
</pre>
|
||
<p>
|
||
For virtual public functions not returning <code class="computeroutput"><span class="keyword">void</span></code>,
|
||
programmers must also pass a reference to the function return value as the
|
||
second argument to <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45028038882752.html" title="Function template public_function">boost::contract::public_function</a></code>.
|
||
In this case, the library will pass this return value reference to the postcondition
|
||
functor that must therefore take one single argument matching the return
|
||
type, otherwise this library will generate a compile-time error (the functor
|
||
parameter can be a constant reference <code class="computeroutput"><span class="keyword">const</span><span class="special">&</span></code> to avoid extra copies of the return
|
||
value): <a href="#ftn.boost_contract.tutorial.virtual_public_functions.f2" class="footnote" name="boost_contract.tutorial.virtual_public_functions.f2"><sup class="footnote">[41]</sup></a>
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">u</span> <span class="special">{</span>
|
||
<span class="keyword">public</span><span class="special">:</span>
|
||
<span class="comment">// A void virtual public function (that does not override).</span>
|
||
<span class="keyword">virtual</span> <span class="identifier">t</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">t_1</span> <span class="identifier">a_1</span><span class="special">,</span> <span class="special">...,</span> <span class="identifier">t_n</span> <span class="identifier">a_n</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">virtual_</span><span class="special">*</span> <span class="identifier">v</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="special">{</span>
|
||
<span class="identifier">t</span> <span class="identifier">result</span><span class="special">;</span>
|
||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">public_function</span><span class="special">(</span>
|
||
<span class="identifier">v</span><span class="special">,</span> <span class="identifier">result</span><span class="special">,</span> <span class="keyword">this</span><span class="special">)</span> <span class="comment">// Result parameter...</span>
|
||
<span class="special">.</span><span class="identifier">precondition</span><span class="special">([&]</span> <span class="special">{</span> <span class="special">...</span> <span class="special">})</span>
|
||
<span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">(</span><span class="identifier">t</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">result</span><span class="special">)</span> <span class="special">{</span> <span class="special">...</span> <span class="special">})</span> <span class="comment">// ...so unary functor.</span>
|
||
<span class="special">.</span><span class="identifier">except</span><span class="special">([&]</span> <span class="special">{</span> <span class="special">...</span> <span class="special">})</span>
|
||
<span class="special">;</span>
|
||
|
||
<span class="special">...</span> <span class="comment">// Assign `result` at each return.</span>
|
||
<span class="special">}</span>
|
||
|
||
<span class="special">...</span>
|
||
<span class="special">}</span>
|
||
</pre>
|
||
<div class="important"><table border="0" summary="Important">
|
||
<tr>
|
||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../doc/src/images/important.png"></td>
|
||
<th align="left">Important</th>
|
||
</tr>
|
||
<tr><td align="left" valign="top">
|
||
<p>
|
||
It is the responsibility of the programmers to pass the extra virtual parameter
|
||
<code class="computeroutput"><span class="identifier">v</span></code> to all <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OLDOF.html" title="Macro BOOST_CONTRACT_OLDOF">BOOST_CONTRACT_OLDOF</a></code>
|
||
and <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45028038882752.html" title="Function template public_function">boost::contract::public_function</a></code>
|
||
calls within virtual public functions, and also to pass the return value
|
||
reference after <code class="computeroutput"><span class="identifier">v</span></code> to <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45028038882752.html" title="Function template public_function">boost::contract::public_function</a></code>
|
||
for non-void virtual public functions. This library cannot automatically
|
||
generate compile-time errors if programmers fail to do so (but in general
|
||
this will prevent the library from correctly checking contracts at run-time).
|
||
<a href="#ftn.boost_contract.tutorial.virtual_public_functions.f3" class="footnote" name="boost_contract.tutorial.virtual_public_functions.f3"><sup class="footnote">[42]</sup></a>
|
||
</p>
|
||
<p>
|
||
<span class="bold"><strong>Mnemonics:</strong></span>
|
||
</p>
|
||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||
When <code class="computeroutput"><span class="identifier">v</span></code> is present, always
|
||
pass it as the first argument to <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45028038882752.html" title="Function template public_function">boost::contract::public_function</a></code>
|
||
and <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OLDOF.html" title="Macro BOOST_CONTRACT_OLDOF">BOOST_CONTRACT_OLDOF</a></code>.
|
||
</p></blockquote></div>
|
||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||
Always pass <code class="computeroutput"><span class="identifier">result</span></code> to
|
||
<code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45028038882752.html" title="Function template public_function">boost::contract::public_function</a></code>
|
||
right after <code class="computeroutput"><span class="identifier">v</span></code> for non-void
|
||
functions.
|
||
</p></blockquote></div>
|
||
</td></tr>
|
||
</table></div>
|
||
<p>
|
||
For the rest, considerations made in <a class="link" href="tutorial.html#boost_contract.tutorial.public_functions" title="Public Functions">Public
|
||
Functions</a> apply to virtual public functions as well.
|
||
</p>
|
||
<div class="note"><table border="0" summary="Note">
|
||
<tr>
|
||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
|
||
<th align="left">Note</th>
|
||
</tr>
|
||
<tr><td align="left" valign="top"><p>
|
||
A virtual public function should always call <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45028038882752.html" title="Function template public_function">boost::contract::public_function</a></code>
|
||
(even if it has no preconditions, no postconditions, no exception guarantees,
|
||
and its class has no invariants), otherwise this library will not be able
|
||
to correctly use it for subcontracting.
|
||
</p></td></tr>
|
||
</table></div>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="boost_contract.tutorial.public_function_overrides__subcontracting_"></a><a class="link" href="tutorial.html#boost_contract.tutorial.public_function_overrides__subcontracting_" title="Public Function Overrides (Subcontracting)">Public
|
||
Function Overrides (Subcontracting)</a>
|
||
</h3></div></div></div>
|
||
<p>
|
||
Contracts for public functions are programmed using <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45028038882752.html" title="Function template public_function">boost::contract::public_function</a></code>.
|
||
In this section, let's consider public functions (virtual or not) that override
|
||
virtual public functions from one or more of their public base classes. For
|
||
example (see <a href="../../../example/features/public.cpp" target="_top"><code class="literal">public.cpp</code></a>):
|
||
<a href="#ftn.boost_contract.tutorial.public_function_overrides__subcontracting_.f0" class="footnote" name="boost_contract.tutorial.public_function_overrides__subcontracting_.f0"><sup class="footnote">[43]</sup></a>
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">identifiers</span>
|
||
<span class="preprocessor">#define</span> <span class="identifier">BASES</span> <span class="keyword">public</span> <span class="identifier">unique_identifiers</span>
|
||
<span class="special">:</span> <span class="identifier">BASES</span>
|
||
<span class="special">{</span>
|
||
<span class="keyword">public</span><span class="special">:</span>
|
||
<span class="keyword">typedef</span> <span class="identifier">BOOST_CONTRACT_BASE_TYPES</span><span class="special">(</span><span class="identifier">BASES</span><span class="special">)</span> <span class="identifier">base_types</span><span class="special">;</span> <span class="comment">// Bases typedef.</span>
|
||
<span class="preprocessor">#undef</span> <span class="identifier">BASES</span>
|
||
|
||
<span class="keyword">void</span> <span class="identifier">invariant</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="comment">// Check in AND with bases.</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">empty</span><span class="special">()</span> <span class="special">==</span> <span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">0</span><span class="special">));</span>
|
||
<span class="special">}</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">public</span><span class="special">:</span>
|
||
<span class="comment">// Contract for a public function override.</span>
|
||
<span class="keyword">int</span> <span class="identifier">push_back</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">id</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">virtual_</span><span class="special">*</span> <span class="identifier">v</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="comment">/* override */</span> <span class="special">{</span>
|
||
<span class="keyword">int</span> <span class="identifier">result</span><span class="special">;</span>
|
||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_ptr</span><span class="special"><</span><span class="keyword">bool</span><span class="special">></span> <span class="identifier">old_find</span> <span class="special">=</span>
|
||
<span class="identifier">BOOST_CONTRACT_OLDOF</span><span class="special">(</span><span class="identifier">v</span><span class="special">,</span> <span class="identifier">find</span><span class="special">(</span><span class="identifier">id</span><span class="special">));</span>
|
||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_ptr</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">old_size</span> <span class="special">=</span>
|
||
<span class="identifier">BOOST_CONTRACT_OLDOF</span><span class="special">(</span><span class="identifier">v</span><span class="special">,</span> <span class="identifier">size</span><span class="special">());</span>
|
||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">public_function</span><span class="special"><</span>
|
||
<span class="identifier">override_push_back</span> <span class="comment">// Pass override type plus below function pointer...</span>
|
||
<span class="special">>(</span><span class="identifier">v</span><span class="special">,</span> <span class="identifier">result</span><span class="special">,</span> <span class="special">&</span><span class="identifier">identifiers</span><span class="special">::</span><span class="identifier">push_back</span><span class="special">,</span> <span class="keyword">this</span><span class="special">,</span> <span class="identifier">id</span><span class="special">)</span> <span class="comment">// ...and arguments.</span>
|
||
<span class="special">.</span><span class="identifier">precondition</span><span class="special">([&]</span> <span class="special">{</span> <span class="comment">// Check in OR with bases.</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">id</span> <span class="special">>=</span> <span class="number">0</span><span class="special">);</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">find</span><span class="special">(</span><span class="identifier">id</span><span class="special">));</span> <span class="comment">// ID can be already present.</span>
|
||
<span class="special">})</span>
|
||
<span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">(</span><span class="keyword">int</span> <span class="keyword">const</span> <span class="identifier">result</span><span class="special">)</span> <span class="special">{</span> <span class="comment">// Check in AND with bases.</span>
|
||
<span class="keyword">if</span><span class="special">(*</span><span class="identifier">old_find</span><span class="special">)</span> <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">old_size</span><span class="special">);</span>
|
||
<span class="special">})</span>
|
||
<span class="special">;</span>
|
||
|
||
<span class="comment">// Function body.</span>
|
||
<span class="keyword">if</span><span class="special">(!</span><span class="identifier">find</span><span class="special">(</span><span class="identifier">id</span><span class="special">))</span> <span class="identifier">unique_identifiers</span><span class="special">::</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">id</span><span class="special">);</span> <span class="comment">// Else, do nothing.</span>
|
||
<span class="keyword">return</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">id</span><span class="special">;</span>
|
||
<span class="special">}</span>
|
||
<span class="identifier">BOOST_CONTRACT_OVERRIDE</span><span class="special">(</span><span class="identifier">push_back</span><span class="special">)</span> <span class="comment">// Define `override_push_back`.</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"> <span class="comment">/* ... */</span>
|
||
<span class="special">};</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
The extra <code class="computeroutput"><span class="keyword">typedef</span></code> declared using
|
||
<code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_BASE_TYPES.html" title="Macro BOOST_CONTRACT_BASE_TYPES">BOOST_CONTRACT_BASE_TYPES</a></code>
|
||
is required by this library for derived classes and it is internally used
|
||
to detect base classes for subcontracting (see <a class="link" href="tutorial.html#boost_contract.tutorial.base_classes__subcontracting_" title="Base Classes (Subcontracting)">Base
|
||
Classes</a>). This library will generate a compile-time error if there
|
||
is no suitable virtual function to override in any of the public base classes
|
||
for subcontracting. <a href="#ftn.boost_contract.tutorial.public_function_overrides__subcontracting_.f1" class="footnote" name="boost_contract.tutorial.public_function_overrides__subcontracting_.f1"><sup class="footnote">[44]</sup></a>
|
||
</p>
|
||
<p>
|
||
When called from public function overrides, the <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45028038882752.html" title="Function template public_function">boost::contract::public_function</a></code>
|
||
function template takes an explicit template argument <code class="computeroutput"><span class="identifier">override_</span></code><code class="literal"><span class="emphasis"><em>function-name</em></span></code>
|
||
that must be defined using <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OVERRIDE.html" title="Macro BOOST_CONTRACT_OVERRIDE">BOOST_CONTRACT_OVERRIDE</a></code>:
|
||
</p>
|
||
<pre class="programlisting"><span class="identifier">BOOST_CONTRACT_OVERRIDE</span><span class="special">(</span><code class="literal"><span class="emphasis"><em>function-name</em></span></code><span class="special">)</span>
|
||
</pre>
|
||
<p>
|
||
This can be declared at any point in the public section of the enclosing
|
||
class (see <a class="link" href="advanced.html#boost_contract.advanced.access_specifiers" title="Access Specifiers">Access
|
||
Specifiers</a> to use <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OVERRIDE.html" title="Macro BOOST_CONTRACT_OVERRIDE">BOOST_CONTRACT_OVERRIDE</a></code>
|
||
also in a non-public section of the class). <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OVERRIDE.html" title="Macro BOOST_CONTRACT_OVERRIDE">BOOST_CONTRACT_OVERRIDE</a></code>
|
||
is used only once in a class for a given function name and overloaded functions
|
||
can reuse the same <code class="literal">override_<span class="emphasis"><em>function-name</em></span></code>
|
||
definition (see <a class="link" href="advanced.html#boost_contract.advanced.function_overloads" title="Function Overloads">Function
|
||
Overloads</a>). <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45028038910320.html" title="Macro BOOST_CONTRACT_NAMED_OVERRIDE">BOOST_CONTRACT_NAMED_OVERRIDE</a></code>
|
||
can be used to generate a name different than <code class="literal">override_<span class="emphasis"><em>function-name</em></span></code>
|
||
(e.g., to avoid generating C++ reserved names containing double underscores
|
||
"<code class="computeroutput"><span class="identifier">__</span></code>" for function
|
||
names that already start with an underscore "<code class="computeroutput"><span class="identifier">_</span></code>",
|
||
see <a class="link" href="advanced.html#boost_contract.advanced.named_overrides" title="Named Overrides">Named Overrides</a>).
|
||
For convenience <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OVERRIDES.html" title="Macro BOOST_CONTRACT_OVERRIDES">BOOST_CONTRACT_OVERRIDES</a></code>
|
||
can be used with multiple function names instead of repeating <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OVERRIDE.html" title="Macro BOOST_CONTRACT_OVERRIDE">BOOST_CONTRACT_OVERRIDE</a></code> for each
|
||
function name (on compilers that support variadic macros). For example, for
|
||
three functions named <code class="computeroutput"><span class="identifier">f</span></code>,
|
||
<code class="computeroutput"><span class="identifier">g</span></code>, and <code class="computeroutput"><span class="identifier">h</span></code>
|
||
(but same for any other number of functions), the following:
|
||
</p>
|
||
<pre class="programlisting"><span class="identifier">BOOST_CONTRACT_OVERRIDES</span><span class="special">(</span><span class="identifier">f</span><span class="special">,</span> <span class="identifier">g</span><span class="special">,</span> <span class="identifier">h</span><span class="special">)</span>
|
||
</pre>
|
||
<p>
|
||
Is equivalent to: <a href="#ftn.boost_contract.tutorial.public_function_overrides__subcontracting_.f2" class="footnote" name="boost_contract.tutorial.public_function_overrides__subcontracting_.f2"><sup class="footnote">[45]</sup></a>
|
||
</p>
|
||
<pre class="programlisting"><span class="identifier">BOOST_CONTRACT_OVERRIDE</span><span class="special">(</span><span class="identifier">f</span><span class="special">)</span>
|
||
<span class="identifier">BOOST_CONTRACT_OVERRIDE</span><span class="special">(</span><span class="identifier">g</span><span class="special">)</span>
|
||
<span class="identifier">BOOST_CONTRACT_OVERRIDE</span><span class="special">(</span><span class="identifier">h</span><span class="special">)</span>
|
||
</pre>
|
||
<p>
|
||
Public function overrides must always list the extra trailing parameter of
|
||
type <code class="computeroutput"><a class="link" href="../boost/contract/virtual_.html" title="Class virtual_">boost::contract::virtual_</a></code><code class="computeroutput"><span class="special">*</span></code> with default value <code class="computeroutput"><span class="number">0</span></code>
|
||
(i.e., <code class="computeroutput"><span class="keyword">nullptr</span></code>), even when they
|
||
are not declared <code class="computeroutput"><span class="keyword">virtual</span></code>, if
|
||
this parameter is present in the signature of the virtual function being
|
||
overridden from base classes. Programmers must pass the extra virtual parameter
|
||
as the very first argument to all <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OLDOF.html" title="Macro BOOST_CONTRACT_OLDOF">BOOST_CONTRACT_OLDOF</a></code>
|
||
and <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45028038882752.html" title="Function template public_function">boost::contract::public_function</a></code>
|
||
calls in the public function override definition (see <a class="link" href="tutorial.html#boost_contract.tutorial.virtual_public_functions" title="Virtual Public Functions">Virtual
|
||
Public Functions</a>).
|
||
</p>
|
||
<p>
|
||
When called from public function overrides, the <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45028038882752.html" title="Function template public_function">boost::contract::public_function</a></code>
|
||
function takes a pointer to the enclosing function, the object <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> (because
|
||
public function overrides check class invariants, see <a class="link" href="tutorial.html#boost_contract.tutorial.class_invariants" title="Class Invariants">Class
|
||
Invariants</a>), and references to each function argument in the order
|
||
they appear in the function declaration. <a href="#ftn.boost_contract.tutorial.public_function_overrides__subcontracting_.f3" class="footnote" name="boost_contract.tutorial.public_function_overrides__subcontracting_.f3"><sup class="footnote">[46]</sup></a> For public function overrides returning <code class="computeroutput"><span class="keyword">void</span></code>:
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">u</span> <span class="special">{</span>
|
||
<span class="keyword">public</span><span class="special">:</span>
|
||
<span class="comment">// A void public function override.</span>
|
||
<span class="keyword">void</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">t_1</span> <span class="identifier">a_1</span><span class="special">,</span> <span class="special">...,</span> <span class="identifier">t_n</span> <span class="identifier">a_n</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">virtual_</span><span class="special">*</span> <span class="identifier">v</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="comment">/* override */</span> <span class="special">{</span>
|
||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">public_function</span><span class="special"><</span><span class="identifier">override_f</span><span class="special">>(</span>
|
||
<span class="identifier">v</span><span class="special">,</span> <span class="special">&</span><span class="identifier">u</span><span class="special">::</span><span class="identifier">f</span><span class="special">,</span> <span class="keyword">this</span><span class="special">,</span> <span class="identifier">a_1</span><span class="special">,</span> <span class="special">...,</span> <span class="identifier">a_n</span><span class="special">)</span> <span class="comment">// No result parameter...</span>
|
||
<span class="special">.</span><span class="identifier">precondition</span><span class="special">([&]</span> <span class="special">{</span> <span class="special">...</span> <span class="special">})</span>
|
||
<span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">{</span> <span class="special">...</span> <span class="special">})</span> <span class="comment">// ...so nullary functor.</span>
|
||
<span class="special">.</span><span class="identifier">except</span><span class="special">([&]</span> <span class="special">{</span> <span class="special">...</span> <span class="special">})</span>
|
||
<span class="special">;</span>
|
||
|
||
<span class="special">...</span>
|
||
<span class="special">}</span>
|
||
<span class="identifier">BOOST_CONTRACT_OVERRIDE</span><span class="special">(</span><span class="identifier">f</span><span class="special">)</span>
|
||
|
||
<span class="special">...</span>
|
||
<span class="special">}</span>
|
||
</pre>
|
||
<p>
|
||
For public function overrides not returning <code class="computeroutput"><span class="keyword">void</span></code>,
|
||
programmers must also pass a reference to the function return value as the
|
||
second argument to <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45028038882752.html" title="Function template public_function">boost::contract::public_function</a></code>
|
||
(this library will generate a compile-time error otherwise). <a href="#ftn.boost_contract.tutorial.public_function_overrides__subcontracting_.f4" class="footnote" name="boost_contract.tutorial.public_function_overrides__subcontracting_.f4"><sup class="footnote">[47]</sup></a> In this case, the library will pass this return value reference
|
||
to the postcondition functor that must therefore take one single argument
|
||
matching the return type, otherwise this library will generate a compile-time
|
||
error (the functor parameter can be a constant reference <code class="computeroutput"><span class="keyword">const</span><span class="special">&</span></code> to avoid extra copies of the return
|
||
value, similarly to non-overriding non-void <a class="link" href="tutorial.html#boost_contract.tutorial.virtual_public_functions" title="Virtual Public Functions">Virtual
|
||
Public Functions</a>):
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">u</span> <span class="special">{</span>
|
||
<span class="keyword">public</span><span class="special">:</span>
|
||
<span class="comment">// A non-void public function override.</span>
|
||
<span class="identifier">t</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">t_1</span> <span class="identifier">a_1</span><span class="special">,</span> <span class="special">...,</span> <span class="identifier">t_n</span> <span class="identifier">a_n</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">virtual_</span><span class="special">*</span> <span class="identifier">v</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="comment">/* override */</span> <span class="special">{</span>
|
||
<span class="identifier">t</span> <span class="identifier">result</span><span class="special">;</span>
|
||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">public_function</span><span class="special"><</span><span class="identifier">override_f</span><span class="special">>(</span>
|
||
<span class="identifier">v</span><span class="special">,</span> <span class="identifier">result</span><span class="special">,</span> <span class="special">&</span><span class="identifier">u</span><span class="special">::</span><span class="identifier">f</span><span class="special">,</span> <span class="keyword">this</span><span class="special">,</span> <span class="identifier">a_1</span><span class="special">,</span> <span class="special">...,</span> <span class="identifier">a_n</span><span class="special">)</span> <span class="comment">// Result parameter...</span>
|
||
<span class="special">.</span><span class="identifier">precondition</span><span class="special">([&]</span> <span class="special">{</span> <span class="special">...</span> <span class="special">})</span>
|
||
<span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">(</span><span class="identifier">t</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">result</span><span class="special">)</span> <span class="special">{</span> <span class="special">...</span> <span class="special">})</span> <span class="comment">// ...so unary functor.</span>
|
||
<span class="special">.</span><span class="identifier">except</span><span class="special">([&]</span> <span class="special">{</span> <span class="special">...</span> <span class="special">})</span>
|
||
<span class="special">;</span>
|
||
|
||
<span class="special">...</span> <span class="comment">// Assign `result` at each return.</span>
|
||
<span class="special">}</span>
|
||
<span class="identifier">BOOST_CONTRACT_OVERRIDE</span><span class="special">(</span><span class="identifier">f</span><span class="special">)</span>
|
||
|
||
<span class="special">...</span>
|
||
<span class="special">}</span>
|
||
</pre>
|
||
<p>
|
||
This library will throw <code class="computeroutput"><a class="link" href="../boost/contract/bad_virtual_result_cast.html" title="Class bad_virtual_result_cast">boost::contract::bad_virtual_result_cast</a></code>
|
||
if programmers specify return values for public function overrides in derived
|
||
classes that are not consistent with the return types of the virtual public
|
||
functions being overridden in the base classes. <a href="#ftn.boost_contract.tutorial.public_function_overrides__subcontracting_.f5" class="footnote" name="boost_contract.tutorial.public_function_overrides__subcontracting_.f5"><sup class="footnote">[48]</sup></a>
|
||
</p>
|
||
<div class="important"><table border="0" summary="Important">
|
||
<tr>
|
||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../doc/src/images/important.png"></td>
|
||
<th align="left">Important</th>
|
||
</tr>
|
||
<tr><td align="left" valign="top">
|
||
<p>
|
||
It is the responsibility of the programmers to pass the extra virtual parameter
|
||
<code class="computeroutput"><span class="identifier">v</span></code> to all <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OLDOF.html" title="Macro BOOST_CONTRACT_OLDOF">BOOST_CONTRACT_OLDOF</a></code>
|
||
and <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45028038882752.html" title="Function template public_function">boost::contract::public_function</a></code>
|
||
calls within public function overrides, and also to pass the return value
|
||
reference after <code class="computeroutput"><span class="identifier">v</span></code> to <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45028038882752.html" title="Function template public_function">boost::contract::public_function</a></code>
|
||
for non-void public function overrides. This library cannot always generate
|
||
compile-time errors if programmers fail to do so (but in general this will
|
||
prevent the library from correctly checking contracts at run-time).
|
||
</p>
|
||
<p>
|
||
<span class="bold"><strong>Mnemonics:</strong></span>
|
||
</p>
|
||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||
When <code class="computeroutput"><span class="identifier">override_</span><span class="special">...</span></code>
|
||
is present, always pass it as template parameter to <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45028038882752.html" title="Function template public_function">boost::contract::public_function</a></code>.
|
||
</p></blockquote></div>
|
||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||
When <code class="computeroutput"><span class="identifier">v</span></code> is present, always
|
||
pass it as the first argument to <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45028038882752.html" title="Function template public_function">boost::contract::public_function</a></code>
|
||
and <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_OLDOF.html" title="Macro BOOST_CONTRACT_OLDOF">BOOST_CONTRACT_OLDOF</a></code>.
|
||
</p></blockquote></div>
|
||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||
Always pass <code class="computeroutput"><span class="identifier">result</span></code> to
|
||
<code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45028038882752.html" title="Function template public_function">boost::contract::public_function</a></code>
|
||
right after <code class="computeroutput"><span class="identifier">v</span></code> for non-void
|
||
functions.
|
||
</p></blockquote></div>
|
||
</td></tr>
|
||
</table></div>
|
||
<p>
|
||
At construction, the <code class="computeroutput"><a class="link" href="../boost/contract/check.html" title="Class check">boost::contract::check</a></code>
|
||
RAII object for public function overrides does the following (enclosing public
|
||
function override entry):
|
||
</p>
|
||
<div class="orderedlist"><ol class="orderedlist" type="1">
|
||
<li class="listitem">
|
||
Check static and non-static class invariants for all overridden bases
|
||
and for the derived class in <a class="link" href="contract_programming_overview.html#and_anchor"><code class="literal"><span class="emphasis"><em>AND</em></span></code></a>
|
||
with each other, by calling <code class="literal"><span class="emphasis"><em>type-of</em></span>(<span class="emphasis"><em>overridden-base_1</em></span>)</code><code class="computeroutput"><span class="special">::</span><span class="identifier">static_invariant</span><span class="special">()</span></code> <a class="link" href="contract_programming_overview.html#and_anchor"><code class="literal"><span class="emphasis"><em>AND</em></span></code></a>
|
||
<code class="literal"><span class="emphasis"><em>overridden-base_1</em></span></code><code class="computeroutput"><span class="special">.</span><span class="identifier">invariant</span><span class="special">()</span></code> <a class="link" href="contract_programming_overview.html#and_anchor"><code class="literal"><span class="emphasis"><em>AND</em></span></code></a>...
|
||
<code class="literal"><span class="emphasis"><em>type-of</em></span>(<span class="emphasis"><em>overridden-base_n</em></span>)</code><code class="computeroutput"><span class="special">::</span><span class="identifier">static_invariant</span><span class="special">()</span></code> <a class="link" href="contract_programming_overview.html#and_anchor"><code class="literal"><span class="emphasis"><em>AND</em></span></code></a>
|
||
<code class="literal"><span class="emphasis"><em>overridden-base_n</em></span></code><code class="computeroutput"><span class="special">.</span><span class="identifier">invariant</span><span class="special">()</span></code> <a class="link" href="contract_programming_overview.html#and_anchor"><code class="literal"><span class="emphasis"><em>AND</em></span></code></a>
|
||
<code class="literal"><span class="emphasis"><em>type-of</em></span></code><code class="computeroutput"><span class="special">(*</span><span class="keyword">this</span><span class="special">)::</span><span class="identifier">static_invariant</span><span class="special">()</span></code>
|
||
<a class="link" href="contract_programming_overview.html#and_anchor"><code class="literal"><span class="emphasis"><em>AND</em></span></code></a>
|
||
<code class="computeroutput"><span class="keyword">this</span><span class="special">-></span><span class="identifier">invariant</span><span class="special">()</span></code>.
|
||
</li>
|
||
<li class="listitem">
|
||
Check preconditions for all overridden base functions and for the overriding
|
||
derived function in <a class="link" href="contract_programming_overview.html#or_anchor"><code class="literal"><span class="emphasis"><em>OR</em></span></code></a>
|
||
with each other, by calling the nullary functors <code class="literal"><span class="emphasis"><em>r_1</em></span></code><code class="computeroutput"><span class="special">()</span></code> <a class="link" href="contract_programming_overview.html#or_anchor"><code class="literal"><span class="emphasis"><em>OR</em></span></code></a>...
|
||
<code class="literal"><span class="emphasis"><em>r_n</em></span></code><code class="computeroutput"><span class="special">()</span></code>
|
||
<a class="link" href="contract_programming_overview.html#or_anchor"><code class="literal"><span class="emphasis"><em>OR</em></span></code></a>
|
||
<code class="literal"><span class="emphasis"><em>r</em></span></code><code class="computeroutput"><span class="special">()</span></code>
|
||
passed to <code class="computeroutput"><span class="special">.</span><span class="identifier">precondition</span><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>r_1</em></span></code><code class="computeroutput"><span class="special">)</span></code>, ... <code class="computeroutput"><span class="special">.</span><span class="identifier">precondition</span><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>r_n</em></span></code><code class="computeroutput"><span class="special">)</span></code>, <code class="computeroutput"><span class="special">.</span><span class="identifier">precondition</span><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>r</em></span></code><code class="computeroutput"><span class="special">)</span></code> for all of the overridden and overriding
|
||
functions respectively.
|
||
</li>
|
||
</ol></div>
|
||
<p>
|
||
At destruction instead (enclosing public function override exit):
|
||
</p>
|
||
<div class="orderedlist"><ol class="orderedlist" type="1">
|
||
<li class="listitem">
|
||
Check static and non-static class invariants for all overridden bases
|
||
and for the derived class in <a class="link" href="contract_programming_overview.html#and_anchor"><code class="literal"><span class="emphasis"><em>AND</em></span></code></a>
|
||
with each other, by calling <code class="literal"><span class="emphasis"><em>type-of</em></span>(<span class="emphasis"><em>overridden-base_1</em></span>)</code><code class="computeroutput"><span class="special">::</span><span class="identifier">static_invariant</span><span class="special">()</span></code> <a class="link" href="contract_programming_overview.html#and_anchor"><code class="literal"><span class="emphasis"><em>AND</em></span></code></a>
|
||
<code class="literal"><span class="emphasis"><em>overridden-base_1</em></span></code><code class="computeroutput"><span class="special">.</span><span class="identifier">invariant</span><span class="special">()</span></code> <a class="link" href="contract_programming_overview.html#and_anchor"><code class="literal"><span class="emphasis"><em>AND</em></span></code></a>...
|
||
<code class="literal"><span class="emphasis"><em>type-of</em></span>(<span class="emphasis"><em>overridden-base_n</em></span>)</code><code class="computeroutput"><span class="special">::</span><span class="identifier">static_invariant</span><span class="special">()</span></code> <a class="link" href="contract_programming_overview.html#and_anchor"><code class="literal"><span class="emphasis"><em>AND</em></span></code></a>
|
||
<code class="literal"><span class="emphasis"><em>overridden-base_n</em></span></code><code class="computeroutput"><span class="special">.</span><span class="identifier">invariant</span><span class="special">()</span></code> <a class="link" href="contract_programming_overview.html#and_anchor"><code class="literal"><span class="emphasis"><em>AND</em></span></code></a>
|
||
<code class="literal"><span class="emphasis"><em>type-of</em></span></code><code class="computeroutput"><span class="special">(*</span><span class="keyword">this</span><span class="special">)::</span><span class="identifier">static_invariant</span><span class="special">()</span></code>
|
||
<a class="link" href="contract_programming_overview.html#and_anchor"><code class="literal"><span class="emphasis"><em>AND</em></span></code></a>
|
||
<code class="computeroutput"><span class="keyword">this</span><span class="special">-></span><span class="identifier">invariant</span><span class="special">()</span></code>
|
||
(even if the function body threw an exception).
|
||
</li>
|
||
<li class="listitem">
|
||
If the function body did not throw an exception:
|
||
<div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem">
|
||
Check postconditions for all overridden base functions and for
|
||
the overriding derived function in <a class="link" href="contract_programming_overview.html#and_anchor"><code class="literal"><span class="emphasis"><em>AND</em></span></code></a>
|
||
with each other, by calling the nullary functors <code class="literal"><span class="emphasis"><em>s_1</em></span></code><code class="computeroutput"><span class="special">()</span></code> <a class="link" href="contract_programming_overview.html#and_anchor"><code class="literal"><span class="emphasis"><em>AND</em></span></code></a>...
|
||
<code class="literal"><span class="emphasis"><em>s_n</em></span></code><code class="computeroutput"><span class="special">()</span></code>
|
||
<a class="link" href="contract_programming_overview.html#and_anchor"><code class="literal"><span class="emphasis"><em>AND</em></span></code></a>
|
||
<code class="literal"><span class="emphasis"><em>s</em></span></code><code class="computeroutput"><span class="special">()</span></code>
|
||
passed to <code class="computeroutput"><span class="special">.</span><span class="identifier">postcondition</span><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>s_1</em></span></code><code class="computeroutput"><span class="special">)</span></code>, ... <code class="computeroutput"><span class="special">.</span><span class="identifier">postcondition</span><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>s_n</em></span></code><code class="computeroutput"><span class="special">)</span></code>, <code class="computeroutput"><span class="special">.</span><span class="identifier">postcondition</span><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>s</em></span></code><code class="computeroutput"><span class="special">)</span></code> for all of the overridden and
|
||
overriding functions respectively (or the unary functors <code class="literal"><span class="emphasis"><em>s_1</em></span></code><code class="computeroutput"><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>result</em></span></code><code class="computeroutput"><span class="special">)</span></code> <a class="link" href="contract_programming_overview.html#and_anchor"><code class="literal"><span class="emphasis"><em>AND</em></span></code></a>...
|
||
<code class="literal"><span class="emphasis"><em>s_n</em></span></code><code class="computeroutput"><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>result</em></span></code><code class="computeroutput"><span class="special">)</span></code> <a class="link" href="contract_programming_overview.html#and_anchor"><code class="literal"><span class="emphasis"><em>AND</em></span></code></a>
|
||
<code class="literal"><span class="emphasis"><em>s</em></span></code><code class="computeroutput"><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>result</em></span></code><code class="computeroutput"><span class="special">)</span></code> for non-void public function overrides).
|
||
</li></ol></div>
|
||
</li>
|
||
<li class="listitem">
|
||
Else:
|
||
<div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem">
|
||
Check exception guarantees for all overridden base functions and
|
||
for the overriding derived function in <a class="link" href="contract_programming_overview.html#and_anchor"><code class="literal"><span class="emphasis"><em>AND</em></span></code></a>
|
||
with each other, by calling the nullary functors <code class="literal"><span class="emphasis"><em>e_1</em></span></code><code class="computeroutput"><span class="special">()</span></code> <a class="link" href="contract_programming_overview.html#and_anchor"><code class="literal"><span class="emphasis"><em>AND</em></span></code></a>...
|
||
<code class="literal"><span class="emphasis"><em>e_n</em></span></code><code class="computeroutput"><span class="special">()</span></code>
|
||
<a class="link" href="contract_programming_overview.html#and_anchor"><code class="literal"><span class="emphasis"><em>AND</em></span></code></a>
|
||
<code class="literal"><span class="emphasis"><em>e</em></span></code><code class="computeroutput"><span class="special">()</span></code>
|
||
passed to <code class="computeroutput"><span class="special">.</span><span class="identifier">except</span><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>e_1</em></span></code><code class="computeroutput"><span class="special">)</span></code>, ... <code class="computeroutput"><span class="special">.</span><span class="identifier">except</span><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>e_n</em></span></code><code class="computeroutput"><span class="special">)</span></code>, <code class="computeroutput"><span class="special">.</span><span class="identifier">except</span><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>e</em></span></code><code class="computeroutput"><span class="special">)</span></code> for all of the overridden and
|
||
overriding functions respectively.
|
||
</li></ol></div>
|
||
</li>
|
||
</ol></div>
|
||
<p>
|
||
This ensures that contracts and subcontracts of public function overrides
|
||
are correctly checked at run-time in accordance with the <a href="http://en.wikipedia.org/wiki/Liskov_substitution_principle" target="_top">substitution
|
||
principle</a> (see <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.public_function_calls" title="Public Function Calls">Public
|
||
Function Calls</a>).
|
||
</p>
|
||
<p>
|
||
For the rest, considerations made in <a class="link" href="tutorial.html#boost_contract.tutorial.virtual_public_functions" title="Virtual Public Functions">Virtual
|
||
Public Functions</a> apply to public function overrides as well.
|
||
</p>
|
||
<div class="note"><table border="0" summary="Note">
|
||
<tr>
|
||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
|
||
<th align="left">Note</th>
|
||
</tr>
|
||
<tr><td align="left" valign="top"><p>
|
||
A public function override should always call <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45028038882752.html" title="Function template public_function">boost::contract::public_function</a></code>
|
||
(even if it has no preconditions, no postconditions, no exception guarantees,
|
||
and its class has no invariants), otherwise this library will not be able
|
||
to correctly use it for subcontracting.
|
||
</p></td></tr>
|
||
</table></div>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="boost_contract.tutorial.base_classes__subcontracting_"></a><a class="link" href="tutorial.html#boost_contract.tutorial.base_classes__subcontracting_" title="Base Classes (Subcontracting)">Base
|
||
Classes (Subcontracting)</a>
|
||
</h3></div></div></div>
|
||
<p>
|
||
In order for this library to support subcontracting, programmers must specify
|
||
the bases of a derived class declaring a public member type named <code class="computeroutput"><span class="identifier">base_types</span></code> via a <code class="computeroutput"><span class="keyword">typedef</span></code>
|
||
using <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_BASE_TYPES.html" title="Macro BOOST_CONTRACT_BASE_TYPES">BOOST_CONTRACT_BASE_TYPES</a></code>.
|
||
For example (see <a href="../../../example/features/base_types.cpp" target="_top"><code class="literal">base_types.cpp</code></a>):
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">chars</span>
|
||
<span class="preprocessor">#define</span> <span class="identifier">BASES</span> <span class="comment">/* local macro (for convenience) */</span> <span class="special">\</span>
|
||
<span class="keyword">private</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">constructor_precondition</span><span class="special"><</span><span class="identifier">chars</span><span class="special">>,</span> <span class="special">\</span>
|
||
<span class="keyword">public</span> <span class="identifier">unique_chars</span><span class="special">,</span> <span class="special">\</span>
|
||
<span class="keyword">public</span> <span class="keyword">virtual</span> <span class="identifier">pushable</span><span class="special"><</span><span class="keyword">char</span><span class="special">>,</span> <span class="special">\</span>
|
||
<span class="keyword">virtual</span> <span class="keyword">protected</span> <span class="identifier">has_size</span><span class="special">,</span> <span class="special">\</span>
|
||
<span class="keyword">private</span> <span class="identifier">has_empty</span>
|
||
<span class="special">:</span> <span class="identifier">BASES</span> <span class="comment">// Bases of this class.</span>
|
||
<span class="special">{</span>
|
||
<span class="keyword">public</span><span class="special">:</span>
|
||
<span class="keyword">typedef</span> <span class="identifier">BOOST_CONTRACT_BASE_TYPES</span><span class="special">(</span><span class="identifier">BASES</span><span class="special">)</span> <span class="identifier">base_types</span><span class="special">;</span> <span class="comment">// Bases typedef.</span>
|
||
<span class="preprocessor">#undef</span> <span class="identifier">BASES</span> <span class="comment">// Undefine local macro.</span>
|
||
|
||
<span class="comment">/* ... */</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
For convenience, a <span class="emphasis"><em>local macro</em></span> named <code class="computeroutput"><span class="identifier">BASES</span></code>
|
||
can be used to avoid repeating the base list twice (first in the derived
|
||
class declaration <code class="computeroutput"><span class="keyword">class</span> </code><code class="literal"><span class="emphasis"><em>class-name</em></span></code><code class="computeroutput">
|
||
<span class="special">:</span> </code><code class="literal"><span class="emphasis"><em>base-list</em></span></code>
|
||
and then again when invoking <code class="computeroutput"><span class="identifier">BOOST_CONTRACT_BASE_TYPES</span><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>base-list</em></span></code><code class="computeroutput"><span class="special">)</span></code>). Being a local macro, <code class="computeroutput"><span class="identifier">BASES</span></code>
|
||
must be undefined using <code class="computeroutput"><span class="preprocessor">#undef</span>
|
||
<span class="identifier">BASES</span></code> after it is used to declare
|
||
the <code class="computeroutput"><span class="identifier">base_types</span></code> <code class="computeroutput"><span class="keyword">typedef</span></code> (to avoid name clashes and macro redefinition
|
||
errors). <a href="#ftn.boost_contract.tutorial.base_classes__subcontracting_.f0" class="footnote" name="boost_contract.tutorial.base_classes__subcontracting_.f0"><sup class="footnote">[49]</sup></a>
|
||
</p>
|
||
<p>
|
||
<code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_BASE_TYPES.html" title="Macro BOOST_CONTRACT_BASE_TYPES">BOOST_CONTRACT_BASE_TYPES</a></code>
|
||
is a variadic macro and accepts a list of bases separated by commas (see
|
||
<a class="link" href="extras.html#boost_contract.extras.no_macros__and_no_variadic_macros_" title="No Macros (and No Variadic Macros)">No
|
||
Macros</a> to program <code class="computeroutput"><span class="identifier">base_types</span></code>
|
||
without using macros). As already noted in <a class="link" href="tutorial.html#boost_contract.tutorial.constructors" title="Constructors">Constructors</a>,
|
||
when the extra base <code class="computeroutput"><a class="link" href="../boost/contract/constructor_precondition.html" title="Class template constructor_precondition">boost::contract::constructor_precondition</a></code>
|
||
is used to program constructor preconditions, its inheritance access level
|
||
must always be <code class="computeroutput"><span class="keyword">private</span></code> and it
|
||
must be specified as the very first base.
|
||
</p>
|
||
<div class="important"><table border="0" summary="Important">
|
||
<tr>
|
||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../doc/src/images/important.png"></td>
|
||
<th align="left">Important</th>
|
||
</tr>
|
||
<tr><td align="left" valign="top">
|
||
<p>
|
||
Each base passed to <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_BASE_TYPES.html" title="Macro BOOST_CONTRACT_BASE_TYPES">BOOST_CONTRACT_BASE_TYPES</a></code>
|
||
must <span class="emphasis"><em>explicitly</em></span> specify its inheritance access level
|
||
<code class="computeroutput"><span class="keyword">public</span></code>, <code class="computeroutput"><span class="keyword">protected</span></code>,
|
||
or <code class="computeroutput"><span class="keyword">private</span></code> (but <code class="computeroutput"><span class="keyword">virtual</span></code> is optional and can be specified
|
||
either before or after the access level as usual in C++). This library
|
||
will generate a compile-time error if the first base is missing its inheritance
|
||
access level, but this library will not be able to always generate an error
|
||
if the access level is missing for bases after the first one. <a href="#ftn.boost_contract.tutorial.base_classes__subcontracting_.f1" class="footnote" name="boost_contract.tutorial.base_classes__subcontracting_.f1"><sup class="footnote">[50]</sup></a> It is the responsibility of the programmers to make sure that
|
||
all bases passed to <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_BASE_TYPES.html" title="Macro BOOST_CONTRACT_BASE_TYPES">BOOST_CONTRACT_BASE_TYPES</a></code>
|
||
explicitly specify their inheritance access level (inheritance access levels
|
||
are instead optional in C++ because <code class="computeroutput"><span class="keyword">private</span></code>
|
||
is implicitly assumed for <code class="computeroutput"><span class="keyword">class</span></code>
|
||
types and <code class="computeroutput"><span class="keyword">public</span></code> for <code class="computeroutput"><span class="keyword">struct</span></code> types).
|
||
</p>
|
||
<p>
|
||
<span class="bold"><strong>Mnemonics:</strong></span>
|
||
</p>
|
||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||
Always explicitly specify the inheritance access level <code class="computeroutput"><span class="keyword">public</span></code>, <code class="computeroutput"><span class="keyword">protected</span></code>,
|
||
or <code class="computeroutput"><span class="keyword">private</span></code> for base classes
|
||
passed to <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_BASE_TYPES.html" title="Macro BOOST_CONTRACT_BASE_TYPES">BOOST_CONTRACT_BASE_TYPES</a></code>.
|
||
</p></blockquote></div>
|
||
</td></tr>
|
||
</table></div>
|
||
<p>
|
||
See <a class="link" href="advanced.html#boost_contract.advanced.access_specifiers" title="Access Specifiers">Access Specifiers</a>
|
||
to avoid making the <code class="computeroutput"><span class="identifier">base_types</span></code>
|
||
member type <code class="computeroutput"><span class="keyword">public</span></code>. <a href="#ftn.boost_contract.tutorial.base_classes__subcontracting_.f2" class="footnote" name="boost_contract.tutorial.base_classes__subcontracting_.f2"><sup class="footnote">[51]</sup></a> See <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45028039730032.html" title="Macro BOOST_CONTRACT_BASES_TYPEDEF">BOOST_CONTRACT_BASES_TYPEDEF</a></code>
|
||
to use a name different from <code class="computeroutput"><span class="identifier">base_types</span></code>
|
||
(e.g., because <code class="computeroutput"><span class="identifier">base_types</span></code>
|
||
clashes with other names in user-defined classes).
|
||
</p>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="boost_contract.tutorial.static_public_functions"></a><a class="link" href="tutorial.html#boost_contract.tutorial.static_public_functions" title="Static Public Functions">Static
|
||
Public Functions</a>
|
||
</h3></div></div></div>
|
||
<p>
|
||
Contracts for public functions are programmed using <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45028038882752.html" title="Function template public_function">boost::contract::public_function</a></code>.
|
||
In this section, let's consider static public functions. For example (see
|
||
<a href="../../../example/features/static_public.cpp" target="_top"><code class="literal">static_public.cpp</code></a>):
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">C</span><span class="special">></span>
|
||
<span class="keyword">class</span> <span class="identifier">make</span> <span class="special">{</span>
|
||
<span class="keyword">public</span><span class="special">:</span>
|
||
<span class="keyword">static</span> <span class="keyword">void</span> <span class="identifier">static_invariant</span><span class="special">()</span> <span class="special">{</span> <span class="comment">// Static class invariants.</span>
|
||
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">instances</span><span class="special">()</span> <span class="special">>=</span> <span class="number">0</span><span class="special">);</span>
|
||
<span class="special">}</span>
|
||
|
||
<span class="comment">// Contract for a static public function.</span>
|
||
<span class="keyword">static</span> <span class="keyword">int</span> <span class="identifier">instances</span><span class="special">()</span> <span class="special">{</span>
|
||
<span class="comment">// Explicit template parameter `make` (check static invariants).</span>
|
||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">public_function</span><span class="special"><</span><span class="identifier">make</span><span class="special">>();</span>
|
||
|
||
<span class="keyword">return</span> <span class="identifier">instances_</span><span class="special">;</span> <span class="comment">// Function body.</span>
|
||
<span class="special">}</span>
|
||
|
||
<span class="comment">/* ... */</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
It is possible to specify preconditions, postconditions, and exception guarantees
|
||
for static public functions (see <a class="link" href="tutorial.html#boost_contract.tutorial.preconditions" title="Preconditions">Preconditions</a>,
|
||
<a class="link" href="tutorial.html#boost_contract.tutorial.postconditions" title="Postconditions">Postconditions</a>,
|
||
and <a class="link" href="tutorial.html#boost_contract.tutorial.exception_guarantees" title="Exception Guarantees">Exception
|
||
Guarantees</a>). When called from static public functions, <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45028038882752.html" title="Function template public_function">boost::contract::public_function</a></code>
|
||
cannot take the object <code class="computeroutput"><span class="keyword">this</span></code>
|
||
as a parameter (because there is no object <code class="computeroutput"><span class="keyword">this</span></code>
|
||
in static member functions) so the enclosing class type is specified via
|
||
an explicit template parameter as in <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45028038882752.html" title="Function template public_function">boost::contract::public_function</a></code><code class="literal"><<span class="emphasis"><em>class-type</em></span>></code>
|
||
(the class type is required to check static class invariants, see <a class="link" href="tutorial.html#boost_contract.tutorial.class_invariants" title="Class Invariants">Class
|
||
Invariants</a>):
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">u</span> <span class="special">{</span>
|
||
<span class="keyword">public</span><span class="special">:</span>
|
||
<span class="comment">// A static public function.</span>
|
||
<span class="keyword">static</span> <span class="keyword">void</span> <span class="identifier">f</span><span class="special">()</span> <span class="special">{</span>
|
||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">public_function</span><span class="special"><</span><span class="identifier">u</span><span class="special">>()</span> <span class="comment">// Class type `u` as explicit template parameter.</span>
|
||
<span class="special">.</span><span class="identifier">precondition</span><span class="special">([&]</span> <span class="special">{</span> <span class="special">...</span> <span class="special">})</span>
|
||
<span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">{</span> <span class="special">...</span> <span class="special">})</span>
|
||
<span class="special">.</span><span class="identifier">except</span><span class="special">([&]</span> <span class="special">{</span> <span class="special">...</span> <span class="special">})</span>
|
||
<span class="special">;</span>
|
||
|
||
<span class="special">...</span>
|
||
<span class="special">}</span>
|
||
|
||
<span class="special">...</span>
|
||
<span class="special">};</span>
|
||
</pre>
|
||
<p>
|
||
The <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45028038882752.html" title="Function template public_function">boost::contract::public_function</a></code>
|
||
function returns an RAII object that must be assigned to a local variable
|
||
of type <code class="computeroutput"><a class="link" href="../boost/contract/check.html" title="Class check">boost::contract::check</a></code>
|
||
(otherwise this library will generate a run-time error, see <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45028039691696.html" title="Macro BOOST_CONTRACT_ON_MISSING_CHECK_DECL">BOOST_CONTRACT_ON_MISSING_CHECK_DECL</a></code>).
|
||
Furthermore, C++11 <code class="computeroutput"><span class="keyword">auto</span></code> declarations
|
||
cannot be used here and the <code class="computeroutput"><a class="link" href="../boost/contract/check.html" title="Class check">boost::contract::check</a></code>
|
||
type must be explicitly specified (otherwise this library will generate a
|
||
compile-time error prior C++17 and a run-time error post C++17). The static
|
||
public functions body is programmed right after the declaration of this RAII
|
||
object.
|
||
</p>
|
||
<p>
|
||
At construction, the <code class="computeroutput"><a class="link" href="../boost/contract/check.html" title="Class check">boost::contract::check</a></code>
|
||
RAII object for static public functions does the following (enclosing static
|
||
public function entry):
|
||
</p>
|
||
<div class="orderedlist"><ol class="orderedlist" type="1">
|
||
<li class="listitem">
|
||
Check static class invariants, by calling <code class="literal"><span class="emphasis"><em>class-type</em></span></code><code class="computeroutput"><span class="special">::</span><span class="identifier">static_invariant</span><span class="special">()</span></code> (but never non-static class invariants).
|
||
</li>
|
||
<li class="listitem">
|
||
Check preconditions, by calling the nullary functor <code class="literal"><span class="emphasis"><em>r</em></span></code><code class="computeroutput"><span class="special">()</span></code> passed to <code class="computeroutput"><span class="special">.</span><span class="identifier">precondition</span><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>r</em></span></code><code class="computeroutput"><span class="special">)</span></code>.
|
||
</li>
|
||
</ol></div>
|
||
<p>
|
||
At destruction instead (enclosing static public function exit):
|
||
</p>
|
||
<div class="orderedlist"><ol class="orderedlist" type="1">
|
||
<li class="listitem">
|
||
Check static class invariants, by calling <code class="literal"><span class="emphasis"><em>class-type</em></span></code><code class="computeroutput"><span class="special">::</span><span class="identifier">static_invariant</span><span class="special">()</span></code> (even if the function body threw an
|
||
exception, but never non-static class invariants).
|
||
</li>
|
||
<li class="listitem">
|
||
If the function body did not throw an exception:
|
||
<div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem">
|
||
Check postconditions, by calling the nullary functor <code class="literal"><span class="emphasis"><em>s</em></span></code><code class="computeroutput"><span class="special">()</span></code> passed to <code class="computeroutput"><span class="special">.</span><span class="identifier">postcondition</span><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>s</em></span></code><code class="computeroutput"><span class="special">)</span></code>.
|
||
</li></ol></div>
|
||
</li>
|
||
<li class="listitem">
|
||
Else:
|
||
<div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem">
|
||
Check exception guarantees, by calling the nullary functor <code class="literal"><span class="emphasis"><em>e</em></span></code><code class="computeroutput"><span class="special">()</span></code> passed to <code class="computeroutput"><span class="special">.</span><span class="identifier">except</span><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>e</em></span></code><code class="computeroutput"><span class="special">)</span></code>.
|
||
</li></ol></div>
|
||
</li>
|
||
</ol></div>
|
||
<p>
|
||
This ensures that static public function contracts are correctly checked
|
||
at run-time (static public functions do not subcontract because they have
|
||
no object <code class="computeroutput"><span class="keyword">this</span></code> and therefore
|
||
there is no inheritance, see <a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.public_function_calls" title="Public Function Calls">Public
|
||
Function Calls</a>).
|
||
</p>
|
||
<div class="note"><table border="0" summary="Note">
|
||
<tr>
|
||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
|
||
<th align="left">Note</th>
|
||
</tr>
|
||
<tr><td align="left" valign="top"><p>
|
||
A static public function can avoid calling <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45028038882752.html" title="Function template public_function">boost::contract::public_function</a></code>
|
||
for efficiency but only when it has no preconditions, no postconditions,
|
||
no exception guarantees, and its class has no static invariants (the class
|
||
can still have non-static invariants or base classes instead).
|
||
</p></td></tr>
|
||
</table></div>
|
||
</div>
|
||
<div class="footnotes">
|
||
<br><hr style="width:100; text-align:left;margin-left: 0">
|
||
<div id="ftn.boost_contract.tutorial.non_member_functions.f0" class="footnote"><p><a href="#boost_contract.tutorial.non_member_functions.f0" class="para"><sup class="para">[19] </sup></a>
|
||
The name of this local variable is arbitrary, but <code class="computeroutput"><span class="identifier">c</span></code>
|
||
is often used in this documentation for <span class="quote">“<span class="quote">c</span>”</span>heck or <span class="quote">“<span class="quote">c</span>”</span>aminiti
|
||
<code class="literal">;-)</code> .
|
||
</p></div>
|
||
<div id="ftn.boost_contract.tutorial.non_member_functions.f1" class="footnote"><p><a href="#boost_contract.tutorial.non_member_functions.f1" class="para"><sup class="para">[20] </sup></a>
|
||
<span class="bold"><strong>Rationale:</strong></span> C++17 guaranteed copy elision
|
||
on function return value voids the trick this library uses to force a compile-time
|
||
error when <code class="computeroutput"><span class="keyword">auto</span></code> is incorrectly
|
||
used instead of <code class="computeroutput"><a class="link" href="../boost/contract/check.html" title="Class check">boost::contract::check</a></code>.
|
||
The library still generates a run-time error in this case (also on C++17).
|
||
In any case, after reading this documentation it should be evident to programmers
|
||
that <code class="computeroutput"><span class="keyword">auto</span></code> should not be used
|
||
in <code class="computeroutput"><a class="link" href="../boost/contract/check.html" title="Class check">boost::contract::check</a></code>
|
||
declarations so this misuse of <code class="computeroutput"><span class="keyword">auto</span></code>
|
||
should not be an issue in practice.
|
||
</p></div>
|
||
<div id="ftn.boost_contract.tutorial.preconditions.f0" class="footnote"><p><a href="#boost_contract.tutorial.preconditions.f0" class="para"><sup class="para">[21] </sup></a>
|
||
Lambda functions with no parameters can be programmed in C++11 as <code class="computeroutput"><span class="special">[...]</span> <span class="special">()</span> <span class="special">{</span> <span class="special">...</span> <span class="special">}</span></code>
|
||
but also equivalently as <code class="computeroutput"><span class="special">[...]</span> <span class="special">{</span> <span class="special">...</span> <span class="special">}</span></code>.
|
||
This second from is often used in this documentation omitting the empty
|
||
parameter list <code class="computeroutput"><span class="special">()</span></code> for brevity.
|
||
</p></div>
|
||
<div id="ftn.boost_contract.tutorial.preconditions.f1" class="footnote"><p><a href="#boost_contract.tutorial.preconditions.f1" class="para"><sup class="para">[22] </sup></a>
|
||
In this documentation preconditions often capture variables by reference
|
||
to avoid extra copies.
|
||
</p></div>
|
||
<div id="ftn.boost_contract.tutorial.return_values.f0" class="footnote"><p><a href="#boost_contract.tutorial.return_values.f0" class="para"><sup class="para">[23] </sup></a>
|
||
The name of the local variable that holds the return value is arbitrary,
|
||
but <code class="computeroutput"><span class="identifier">result</span></code> is often used
|
||
in this documentation.
|
||
</p></div>
|
||
<div id="ftn.boost_contract.tutorial.old_values.f0" class="footnote"><p><a href="#boost_contract.tutorial.old_values.f0" class="para"><sup class="para">[24] </sup></a>
|
||
The name of a local variable that holds an old value is arbitrary, but
|
||
<code class="literal">old_<span class="emphasis"><em>variable-name</em></span></code> is often used
|
||
in this documentation.
|
||
</p></div>
|
||
<div id="ftn.boost_contract.tutorial.old_values.f1" class="footnote"><p><a href="#boost_contract.tutorial.old_values.f1" class="para"><sup class="para">[25] </sup></a>
|
||
<span class="bold"><strong>Rationale:</strong></span> Old values have to be optional
|
||
values because they need to be left uninitialized when they are not used
|
||
because both postconditions and exception guarantees are disabled (defining
|
||
<code class="computeroutput"><a class="link" href="../BOOST_CO_idm45028039653664.html" title="Macro BOOST_CONTRACT_NO_POSTCONDITIONS">BOOST_CONTRACT_NO_POSTCONDITIONS</a></code>
|
||
and <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_NO_EXCEPTS.html" title="Macro BOOST_CONTRACT_NO_EXCEPTS">BOOST_CONTRACT_NO_EXCEPTS</a></code>).
|
||
That is to avoid old value copies when old values are not used, either
|
||
a pointer or (better) a <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span></code>
|
||
could have been used to achieve that. In addition, old values need to be
|
||
pointers internally allocated by this library so that they are never copied
|
||
twice even when calling an overridden function multiple times to check
|
||
preconditions, postconditions, etc. to implement subcontracting, so a smart
|
||
pointer class template was used.
|
||
</p></div>
|
||
<div id="ftn.boost_contract.tutorial.old_values.f2" class="footnote"><p><a href="#boost_contract.tutorial.old_values.f2" class="para"><sup class="para">[26] </sup></a>
|
||
For example, old value pointers might be null in preconditions when postconditions
|
||
and exception guarantees are disabled defining <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45028039653664.html" title="Macro BOOST_CONTRACT_NO_POSTCONDITIONS">BOOST_CONTRACT_NO_POSTCONDITIONS</a></code>
|
||
and <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_NO_EXCEPTS.html" title="Macro BOOST_CONTRACT_NO_EXCEPTS">BOOST_CONTRACT_NO_EXCEPTS</a></code>
|
||
(but also when checking an overridden virtual public function contract
|
||
via subcontracting, etc.).
|
||
</p></div>
|
||
<div id="ftn.boost_contract.tutorial.class_invariants.f0" class="footnote"><p><a href="#boost_contract.tutorial.class_invariants.f0" class="para"><sup class="para">[27] </sup></a>
|
||
This library uses template meta-programming (SFINAE-based introspection
|
||
techniques) to check invariants only for classes that declare a member
|
||
function named by <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45028039722128.html" title="Macro BOOST_CONTRACT_INVARIANT_FUNC">BOOST_CONTRACT_INVARIANT_FUNC</a></code>.
|
||
</p></div>
|
||
<div id="ftn.boost_contract.tutorial.class_invariants.f1" class="footnote"><p><a href="#boost_contract.tutorial.class_invariants.f1" class="para"><sup class="para">[28] </sup></a>
|
||
In this documentation the <code class="computeroutput"><span class="identifier">invariant</span></code>
|
||
member function is often declared <code class="computeroutput"><span class="keyword">public</span></code>
|
||
for simplicity. However, in production code it might not be acceptable
|
||
to augment the public members of a class adding the <code class="computeroutput"><span class="identifier">invariant</span></code>
|
||
function (and that can be avoided using <code class="computeroutput"><a class="link" href="../boost/contract/access.html" title="Class access">boost::contract::access</a></code>
|
||
as explained in <a class="link" href="advanced.html#boost_contract.advanced.access_specifiers" title="Access Specifiers">Access
|
||
Specifiers</a>).
|
||
</p></div>
|
||
<div id="ftn.boost_contract.tutorial.class_invariants.f2" class="footnote"><p><a href="#boost_contract.tutorial.class_invariants.f2" class="para"><sup class="para">[29] </sup></a>
|
||
This library uses template meta-programming (SFINAE-based introspection
|
||
techniques) to check static invariants only for classes that declare a
|
||
member function named by <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45028039712400.html" title="Macro BOOST_CONTRACT_STATIC_INVARIANT_FUNC">BOOST_CONTRACT_STATIC_INVARIANT_FUNC</a></code>.
|
||
</p></div>
|
||
<div id="ftn.boost_contract.tutorial.class_invariants.f3" class="footnote"><p><a href="#boost_contract.tutorial.class_invariants.f3" class="para"><sup class="para">[30] </sup></a>
|
||
In this documentation the <code class="computeroutput"><span class="identifier">static_invariant</span></code>
|
||
member function is often declared <code class="computeroutput"><span class="keyword">public</span></code>
|
||
for simplicity. However, in production code it might not be acceptable
|
||
to augment the public members of a class adding the <code class="computeroutput"><span class="identifier">static_invariant</span></code>
|
||
function (and that can be avoided using <code class="computeroutput"><a class="link" href="../boost/contract/access.html" title="Class access">boost::contract::access</a></code>
|
||
as explained in <a class="link" href="advanced.html#boost_contract.advanced.access_specifiers" title="Access Specifiers">Access
|
||
Specifiers</a>).
|
||
</p></div>
|
||
<div id="ftn.boost_contract.tutorial.class_invariants.f4" class="footnote"><p><a href="#boost_contract.tutorial.class_invariants.f4" class="para"><sup class="para">[31] </sup></a>
|
||
<span class="bold"><strong>Rationale:</strong></span> In C++, it is not possible
|
||
to overload a member function based on the <code class="computeroutput"><span class="keyword">static</span></code>
|
||
classifier. Therefore, this library has to use different names for the
|
||
member functions checking non-static and static class invariants (namely
|
||
for <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45028039722128.html" title="Macro BOOST_CONTRACT_INVARIANT_FUNC">BOOST_CONTRACT_INVARIANT_FUNC</a></code>
|
||
and for <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45028039712400.html" title="Macro BOOST_CONTRACT_STATIC_INVARIANT_FUNC">BOOST_CONTRACT_STATIC_INVARIANT_FUNC</a></code>).
|
||
</p></div>
|
||
<div id="ftn.boost_contract.tutorial.constructors.f0" class="footnote"><p><a href="#boost_contract.tutorial.constructors.f0" class="para"><sup class="para">[32] </sup></a>
|
||
See <a class="link" href="extras.html#boost_contract.extras.no_lambda_functions__no_c__11_" title="No Lambda Functions (No C++11)">No
|
||
Lambda Functions</a> to enforce this constraint at compile-time (but
|
||
not recommended because of extra boiler-plate code).
|
||
</p></div>
|
||
<div id="ftn.boost_contract.tutorial.constructors.f1" class="footnote"><p><a href="#boost_contract.tutorial.constructors.f1" class="para"><sup class="para">[33] </sup></a>
|
||
There is a MSVC bug that was fixed in MSVC 2013 for which lambdas cannot
|
||
be used in constructor member initialization lists for templates. On MSVC
|
||
compilers with that bug, an extra (static) member function can be used
|
||
(together with <code class="computeroutput"><span class="identifier">bind</span></code> and
|
||
<code class="computeroutput"><span class="identifier">cref</span></code> as needed) to program
|
||
constructor preconditions instead of using lambdas (see <a class="link" href="extras.html#boost_contract.extras.no_lambda_functions__no_c__11_" title="No Lambda Functions (No C++11)">No
|
||
Lambda Functions</a>).
|
||
</p></div>
|
||
<div id="ftn.boost_contract.tutorial.constructors.f2" class="footnote"><p><a href="#boost_contract.tutorial.constructors.f2" class="para"><sup class="para">[34] </sup></a>
|
||
<span class="bold"><strong>Rationale:</strong></span> The <code class="computeroutput"><a class="link" href="../boost/contract/constructor_precondition.html" title="Class template constructor_precondition">boost::contract::constructor_precondition</a></code>
|
||
takes the derived class as its template parameter (using the Curiously
|
||
Recursive Template Pattern, CRTP) so the instantiated template type
|
||
is unique for each derived class. This always avoids base class ambiguity
|
||
resolution errors even when multiple inheritance is used. Note that,
|
||
as already mentioned, virtual inheritance could not be used instead
|
||
of the template parameter here to resolve ambiguities (because virtual
|
||
bases are initialized only once by the outer-most derived class, and
|
||
that would not allow to properly check preconditions of all base classes).
|
||
</p></div>
|
||
<div id="ftn.boost_contract.tutorial.constructors.f3" class="footnote"><p><a href="#boost_contract.tutorial.constructors.f3" class="para"><sup class="para">[35] </sup></a>
|
||
See <a class="link" href="extras.html#boost_contract.extras.no_lambda_functions__no_c__11_" title="No Lambda Functions (No C++11)">No
|
||
Lambda Functions</a> to enforce this constraint at compile-time (but
|
||
not recommended because of extra boiler-plate code).
|
||
</p></div>
|
||
<div id="ftn.boost_contract.tutorial.constructors.f4" class="footnote"><p><a href="#boost_contract.tutorial.constructors.f4" class="para"><sup class="para">[36] </sup></a>
|
||
See <a class="link" href="extras.html#boost_contract.extras.no_lambda_functions__no_c__11_" title="No Lambda Functions (No C++11)">No
|
||
Lambda Functions</a> to enforce these constraints at compile-time (but
|
||
not recommended because of extra boiler-plate code).
|
||
</p></div>
|
||
<div id="ftn.boost_contract.tutorial.destructors.f0" class="footnote"><p><a href="#boost_contract.tutorial.destructors.f0" class="para"><sup class="para">[37] </sup></a>
|
||
See <a class="link" href="extras.html#boost_contract.extras.no_lambda_functions__no_c__11_" title="No Lambda Functions (No C++11)">No
|
||
Lambda Functions</a> to enforce this constraint at compile-time (but
|
||
not recommended because of extra boiler-plate code).
|
||
</p></div>
|
||
<div id="ftn.boost_contract.tutorial.destructors.f1" class="footnote"><p><a href="#boost_contract.tutorial.destructors.f1" class="para"><sup class="para">[38] </sup></a>
|
||
Exceptions guarantees in destructors can access both the object <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> and
|
||
its old value because the object existed before executing the destructor
|
||
body and it still exists given the destructor body failed throwing an exception
|
||
so technically the object should still be properly constructed and satisfy
|
||
its class invariants.
|
||
</p></div>
|
||
<div id="ftn.boost_contract.tutorial.virtual_public_functions.f0" class="footnote"><p><a href="#boost_contract.tutorial.virtual_public_functions.f0" class="para"><sup class="para">[39] </sup></a>
|
||
The name of this extra parameter is arbitrary, but <code class="computeroutput"><span class="identifier">v</span></code>
|
||
is often used in this documentation.
|
||
</p></div>
|
||
<div id="ftn.boost_contract.tutorial.virtual_public_functions.f1" class="footnote"><p><a href="#boost_contract.tutorial.virtual_public_functions.f1" class="para"><sup class="para">[40] </sup></a>
|
||
<span class="bold"><strong>Rationale:</strong></span> The <code class="computeroutput"><a class="link" href="../boost/contract/virtual_.html" title="Class virtual_">boost::contract::virtual_</a></code><code class="computeroutput"><span class="special">*</span></code> parameter is used by this library to determine
|
||
that a function is virtual (in C++ it is not possible to introspect if
|
||
a function is declared <code class="computeroutput"><span class="keyword">virtual</span></code>).
|
||
Furthermore, this parameter is internally used by this library to implement
|
||
subcontracting (specifically to pass result and old values that are evaluated
|
||
by the overriding function to the contracts of overridden virtual functions
|
||
in base classes, and also to check preconditions, postconditions, and exception
|
||
guarantees of overridden virtual functions in <a class="link" href="contract_programming_overview.html#or_anchor"><code class="literal"><span class="emphasis"><em>OR</em></span></code></a>
|
||
and <a class="link" href="contract_programming_overview.html#and_anchor"><code class="literal"><span class="emphasis"><em>AND</em></span></code></a>
|
||
with contracts of the overriding virtual function).
|
||
</p></div>
|
||
<div id="ftn.boost_contract.tutorial.virtual_public_functions.f2" class="footnote"><p><a href="#boost_contract.tutorial.virtual_public_functions.f2" class="para"><sup class="para">[41] </sup></a>
|
||
<span class="bold"><strong>Rationale:</strong></span> The extra function result parameter
|
||
taken by the functor passed to <code class="computeroutput"><span class="special">.</span><span class="identifier">postcondition</span><span class="special">(...)</span></code>
|
||
is used by this library to pass the return value evaluated by the overriding
|
||
function to all its overridden virtual functions to support subcontracting.
|
||
</p></div>
|
||
<div id="ftn.boost_contract.tutorial.virtual_public_functions.f3" class="footnote"><p><a href="#boost_contract.tutorial.virtual_public_functions.f3" class="para"><sup class="para">[42] </sup></a>
|
||
<span class="bold"><strong>Rationale:</strong></span> This library does not require
|
||
programmers to specify the function type when using <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45028038882752.html" title="Function template public_function">boost::contract::public_function</a></code>
|
||
for non-overriding virtual public functions. Therefore, this library
|
||
does not know if the enclosing function has a non-void return type so
|
||
it cannot check if the return value reference is passed as required for
|
||
non-overriding virtual public functions. Instead the function type is
|
||
passed to this library for virtual public function overrides and that
|
||
also allows this library to give a compile-time error if the return value
|
||
reference is missing in those cases.
|
||
</p></div>
|
||
<div id="ftn.boost_contract.tutorial.public_function_overrides__subcontracting_.f0" class="footnote"><p><a href="#boost_contract.tutorial.public_function_overrides__subcontracting_.f0" class="para"><sup class="para">[43] </sup></a>
|
||
In this documentation, function overrides are often marked with the code
|
||
comment <code class="computeroutput"><span class="comment">/* override */</span></code>. On
|
||
compilers that support C++11 virtual specifiers, the <code class="computeroutput"><span class="identifier">override</span></code>
|
||
identifier can be used instead (<code class="computeroutput"><span class="identifier">override</span></code>
|
||
is not used in the documentation simply because virtual specifiers are
|
||
not widely supported yet, even by compilers that support C++11 lambda functions).
|
||
</p></div>
|
||
<div id="ftn.boost_contract.tutorial.public_function_overrides__subcontracting_.f1" class="footnote"><p><a href="#boost_contract.tutorial.public_function_overrides__subcontracting_.f1" class="para"><sup class="para">[44] </sup></a>
|
||
The compile-time error generated by the library in this case is similar
|
||
in principle to the error generated by the C++11 <code class="computeroutput"><span class="identifier">override</span></code>
|
||
specifier, but it is limited to functions with the extra <code class="computeroutput"><a class="link" href="../boost/contract/virtual_.html" title="Class virtual_">boost::contract::virtual_</a></code><code class="computeroutput"><span class="special">*</span></code> parameter and searched recursively only
|
||
in <code class="computeroutput"><span class="keyword">public</span></code> base classes passed
|
||
to <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_BASE_TYPES.html" title="Macro BOOST_CONTRACT_BASE_TYPES">BOOST_CONTRACT_BASE_TYPES</a></code>
|
||
because only those are considered for subcontracting.
|
||
</p></div>
|
||
<div id="ftn.boost_contract.tutorial.public_function_overrides__subcontracting_.f2" class="footnote"><p><a href="#boost_contract.tutorial.public_function_overrides__subcontracting_.f2" class="para"><sup class="para">[45] </sup></a>
|
||
There is no equivalent of <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45028038910320.html" title="Macro BOOST_CONTRACT_NAMED_OVERRIDE">BOOST_CONTRACT_NAMED_OVERRIDE</a></code>
|
||
that operates on multiple function names at once (<code class="computeroutput"><a class="link" href="../BOOST_CO_idm45028038910320.html" title="Macro BOOST_CONTRACT_NAMED_OVERRIDE">BOOST_CONTRACT_NAMED_OVERRIDE</a></code>
|
||
is not expected to be used often so it can simply be repeated multiple
|
||
times when needed).
|
||
</p></div>
|
||
<div id="ftn.boost_contract.tutorial.public_function_overrides__subcontracting_.f3" class="footnote"><p><a href="#boost_contract.tutorial.public_function_overrides__subcontracting_.f3" class="para"><sup class="para">[46] </sup></a>
|
||
<span class="bold"><strong>Rationale:</strong></span> The object <code class="computeroutput"><span class="keyword">this</span></code>
|
||
is passed after the function pointer to follow <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bind</span></code>'s
|
||
syntax. The function pointer and references to all function arguments are
|
||
needed for public function overrides because this library has to internally
|
||
call overridden virtual public functions to check their contracts for subcontracting
|
||
(even if this library will not actually execute the bodies of the overridden
|
||
functions).
|
||
</p></div>
|
||
<div id="ftn.boost_contract.tutorial.public_function_overrides__subcontracting_.f4" class="footnote"><p><a href="#boost_contract.tutorial.public_function_overrides__subcontracting_.f4" class="para"><sup class="para">[47] </sup></a>
|
||
<span class="bold"><strong>Rationale:</strong></span> As for non-overriding virtual
|
||
public functions, also public function overrides use the extra return value
|
||
parameter to pass it to the overridden functions when subcontracting. In
|
||
the case of public function overrides, this library has the function pointer
|
||
so it will generate a compile-time error if the function is non-void and
|
||
programmers forget to specify the extra return value parameter (this extra
|
||
error checking is not possible instead for non-overriding virtual public
|
||
functions because their contracts do not take the function pointer as a
|
||
parameter, see <a class="link" href="tutorial.html#boost_contract.tutorial.virtual_public_functions" title="Virtual Public Functions">Virtual
|
||
Public Functions</a>).
|
||
</p></div>
|
||
<div id="ftn.boost_contract.tutorial.public_function_overrides__subcontracting_.f5" class="footnote"><p><a href="#boost_contract.tutorial.public_function_overrides__subcontracting_.f5" class="para"><sup class="para">[48] </sup></a>
|
||
<span class="bold"><strong>Rationale:</strong></span> The <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">bad_any_cast</span></code>
|
||
exception was not used here because it does not print the from- and to-
|
||
type names (so it is not descriptive enough).
|
||
</p></div>
|
||
<div id="ftn.boost_contract.tutorial.base_classes__subcontracting_.f0" class="footnote"><p><a href="#boost_contract.tutorial.base_classes__subcontracting_.f0" class="para"><sup class="para">[49] </sup></a>
|
||
The name of this local macro is arbitrary, but <code class="computeroutput"><span class="identifier">BASES</span></code>
|
||
is often used in this documentation.
|
||
</p></div>
|
||
<div id="ftn.boost_contract.tutorial.base_classes__subcontracting_.f1" class="footnote"><p><a href="#boost_contract.tutorial.base_classes__subcontracting_.f1" class="para"><sup class="para">[50] </sup></a>
|
||
<span class="bold"><strong>Rationale:</strong></span> This library explicitly requires
|
||
the inheritance access level because derived classes must subcontract
|
||
only from public bases, but not from protected or private bases (see
|
||
<a class="link" href="contract_programming_overview.html#boost_contract.contract_programming_overview.public_function_calls" title="Public Function Calls">Public
|
||
Function Calls</a>). <code class="computeroutput"><a class="link" href="../BOOST_CONTRACT_BASE_TYPES.html" title="Macro BOOST_CONTRACT_BASE_TYPES">BOOST_CONTRACT_BASE_TYPES</a></code>
|
||
inspects each inheritance access level using preprocessor meta-programming
|
||
and removes non-public bases from the list of bases internally used for
|
||
subcontracting. However, this library cannot always detect when programmers
|
||
forget to specify the inheritance access level because, when commas are
|
||
used to separate template parameters passed to base classes, the preprocessor
|
||
will not be able to correctly use commas to identify the next base class
|
||
token in the inheritance list (the preprocessor cannot distinguish between
|
||
commas that are not protected by round parenthesis, like the ones used
|
||
in templates). Therefore, this library uses the inheritance access level
|
||
keyword <code class="computeroutput"><span class="keyword">public</span></code>, <code class="computeroutput"><span class="keyword">protected</span></code>, or <code class="computeroutput"><span class="keyword">private</span></code>
|
||
instead of commas <code class="computeroutput"><span class="special">,</span></code> for
|
||
the preprocessor to correctly find the next base class token in the inheritance
|
||
list (thus inheritance access levels must always be explicit specified
|
||
by programmers for each base).
|
||
</p></div>
|
||
<div id="ftn.boost_contract.tutorial.base_classes__subcontracting_.f2" class="footnote"><p><a href="#boost_contract.tutorial.base_classes__subcontracting_.f2" class="para"><sup class="para">[51] </sup></a>
|
||
In this documentation the <code class="computeroutput"><span class="identifier">base_type</span></code>
|
||
member type is often declared <code class="computeroutput"><span class="keyword">public</span></code>
|
||
for simplicity. However, in production code it might not be acceptable
|
||
to augment the public members of a class adding the <code class="computeroutput"><span class="identifier">base_types</span></code>
|
||
type (and that can be avoided using <code class="computeroutput"><a class="link" href="../boost/contract/access.html" title="Class access">boost::contract::access</a></code>
|
||
as explained in <a class="link" href="advanced.html#boost_contract.advanced.access_specifiers" title="Access Specifiers">Access
|
||
Specifiers</a>).
|
||
</p></div>
|
||
</div>
|
||
</div>
|
||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||
<td align="left"></td>
|
||
<td align="right"><div class="copyright-footer">Copyright © 2008-2019 Lorenzo Caminiti<p>
|
||
Distributed under the Boost Software License, Version 1.0 (see accompanying
|
||
file LICENSE_1_0.txt or a copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||
</p>
|
||
</div></td>
|
||
</tr></table>
|
||
<hr>
|
||
<div class="spirit-nav">
|
||
<a accesskey="p" href="contract_programming_overview.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="advanced.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||
</div>
|
||
</body>
|
||
</html>
|