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