2211 lines
229 KiB
HTML
2211 lines
229 KiB
HTML
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
|
<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 usages 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_idm45123870548928.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
|
|
the 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
|
|
<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, precondition assertions should not 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 (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><span class="identifier">bool_cond</span><span class="special">)</span>
|
|
<span class="comment">// Or, if `bool_cond` contains commas `,` not already within parenthesis `()`...</span>
|
|
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">((</span><span class="identifier">bool_cond</span><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 and, 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
|
|
<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 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 constructed). 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, postcondition assertions should not modify the
|
|
value of the captured variables (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 (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><span class="identifier">bool_cond</span><span class="special">)</span>
|
|
<span class="comment">// Or, if `bool_cond` has commas `,` not already within parenthesis `()`...</span>
|
|
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">((</span><span class="identifier">bool_cond</span><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 and, 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 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="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="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"><span class="keyword">return</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">return_expr</span><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 constructed). 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 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="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_value_copies_at_body" title="Old Value Copies at Body">Old
|
|
Value Copies at Body</a> for delaying the copy of old values until after
|
|
class invariants (for constructors, destructors, and public functions) and
|
|
preconditions are checked (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>. 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_idm45123870511440.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_idm45123870511440.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
|
|
<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 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 constructed). 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 will not be properly set when the function throws an exception).
|
|
In any case, exception guarantee assertions should not modify the value of
|
|
the captured variables (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 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 domain.
|
|
</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 (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><span class="identifier">bool_cond</span><span class="special">)</span>
|
|
<span class="comment">// Or, if `bool_cond` has commas `,` not already within parenthesis `()`...</span>
|
|
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">((</span><span class="identifier">bool_cond</span><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 and, 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 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 (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><span class="identifier">bool_cond</span><span class="special">)</span>
|
|
<span class="comment">// Or, if `bool_cond` has commas `,` not already within parenthesis `()`...</span>
|
|
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">((</span><span class="identifier">bool_cond</span><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 and, 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_idm45123870579312.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 (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><span class="identifier">bool_cond</span><span class="special">)</span>
|
|
<span class="comment">// Or, if condition has commas `,` not already within parenthesis `()`...</span>
|
|
<span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">((</span><span class="identifier">bool_cond</span><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 and, 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_idm45123870569600.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="identifier">to</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 (but considerations from <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 takes the derived class as template parameter (the Curiously Recursive
|
|
Template Pattern (CRTP) is used here to avoid ambiguity resolution errors
|
|
with multiple inheritance). <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="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_idm45123870548928.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 the 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>
|
|
<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="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++ and in fact they 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_idm45123870548928.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 the 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>
|
|
<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_idm45123869756752.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">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_idm45123869756752.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_idm45123869756752.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_idm45123870548928.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 the 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_idm45123869756752.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_idm45123869756752.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_idm45123869756752.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">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_idm45123869756752.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_idm45123869756752.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_idm45123869756752.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_idm45123869756752.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_idm45123869756752.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_idm45123869756752.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_idm45123869756752.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_idm45123869756752.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_idm45123869756752.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 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 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">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
|
|
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>).
|
|
</p>
|
|
<p>
|
|
When called from public function overrides, the <code class="computeroutput"><a class="link" href="../boost/contract/public_f_idm45123869756752.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><span class="identifier">func_name</span><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>
|
|
in a non-public section of the class instead). <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_idm45123869781472.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_.f1" class="footnote" name="boost_contract.tutorial.public_function_overrides__subcontracting_.f1"><sup class="footnote">[44]</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>
|
|
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_.f2" class="footnote" name="boost_contract.tutorial.public_function_overrides__subcontracting_.f2"><sup class="footnote">[45]</sup></a>
|
|
</p>
|
|
<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> (because
|
|
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_idm45123869756752.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_idm45123869756752.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="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_idm45123869756752.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):
|
|
</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_idm45123869756752.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_idm45123869756752.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">boost::contract::public_functioon</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_idm45123869756752.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_idm45123869756752.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 public function override contracts and subcontracts 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>
|
|
<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_idm45123869756752.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 local macro 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 has been used to
|
|
declare <code class="computeroutput"><span class="identifier">base_types</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_idm45123870587168.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_idm45123869756752.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_idm45123869756752.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 is specified as
|
|
an explicit template parameter (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_idm45123869756752.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_idm45123870548928.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 the 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_idm45123869756752.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 zero-copy guarantee on
|
|
function return values skips 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 is still able to generate a run-time error in this case 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_idm45123870511440.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, so 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 for 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_idm45123870511440.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 <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123870579312.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 <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123870569600.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_idm45123870579312.html" title="Macro BOOST_CONTRACT_INVARIANT_FUNC">BOOST_CONTRACT_INVARIANT_FUNC</a></code>
|
|
and for <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123870569600.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 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 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="keyword">this</span></code> and its old value because the object
|
|
exited before executing the destructor body and it still exists given the
|
|
destructor body failed throwing an exception so 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 pass
|
|
result and old values that are evaluated by the overriding function to
|
|
overridden virtual functions in base classes, and also to check preconditions,
|
|
postconditions, and exception guarantees of overridden virtual functions
|
|
to implement subcontracting.
|
|
</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 when 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_idm45123869756752.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>
|
|
This library does not provider an equivalent of <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123869781472.html" title="Macro BOOST_CONTRACT_NAMED_OVERRIDE">BOOST_CONTRACT_NAMED_OVERRIDE</a></code>
|
|
that operates on multiple function names at once (simply because programmers
|
|
will probably not use <code class="computeroutput"><a class="link" href="../BOOST_CO_idm45123869781472.html" title="Macro BOOST_CONTRACT_NAMED_OVERRIDE">BOOST_CONTRACT_NAMED_OVERRIDE</a></code>
|
|
often in the first place).
|
|
</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>
|
|
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_.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 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 could 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 inspected 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 relies on inheritance access levels
|
|
to program the preprocessor to correctly identify the next base class
|
|
token in the inheritance list (thus inheritance access levels must always
|
|
be explicit specified by programmers).
|
|
</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-2018 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>
|