<html>
<head>
<base href="https://wiki.asterisk.org/wiki">
<link rel="stylesheet" href="/wiki/s/en/2172/18/9/_/styles/combined.css?spaceKey=TOP&forWysiwyg=true" type="text/css">
</head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
<h2><a href="https://wiki.asterisk.org/wiki/pages/viewpage.action?pageId=9568664">C++ Best Practices</a></h2>
<h4>Page <b>edited</b> by <a href="https://wiki.asterisk.org/wiki/display/~beagles">Brent Eagles</a>
</h4>
<br/>
<h4>Changes (1)</h4>
<div id="page-diffs">
<table class="diff" cellpadding="0" cellspacing="0">
<tr><td class="diff-snipped" >...<br></td></tr>
<tr><td class="diff-unchanged" >h3. Avoid volatile <br>The {{volatile}} keyword, by its very definition is compiler specific. Its usage could lead to portability problems and is best avoided. <br></td></tr>
<tr><td class="diff-added-lines" style="background-color: #dfd;"> <br>h3. Do Not Allow Exceptions to "Escape" Destructors <br>An uncaught exception thrown from a destructor when the stack is unwinding due to a prior exception results in {{terminate()}}. If a destructor calls code that may throw, it should surround that code in a {{try/catch}} block. <br> <br>{code:cpp} <br>Foo::~Foo() <br>{ <br> try <br> { <br> // Do a bunch of stuff that may throw. <br> } <br> catch (...) <br> { <br> // You can also catch specific exceptions. <br> } <br>} <br>{code} <br></td></tr>
</table>
</div> <h4>Full Content</h4>
<div class="notificationGreySide">
<div class='panelMacro'><table class='infoMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="/wiki/images/icons/emoticons/information.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>This page is a high level list of general C++ best practices, do's and don'ts, etc.</td></tr></table></div>
<div>
<ul>
<li><a href='#C%2B%2BBestPractices-Don%27tuse%7B%7Bstd%3A%3Aautoptr%7D%7D.Use%7B%7Bboost%3A%3Asharedptr%7D%7Dinstead.'>Don't use <tt>std::auto_ptr</tt>. Use <tt>boost::shared_ptr</tt> instead.</a></li>
<li><a href='#C%2B%2BBestPractices-Watchoutforcyclicreferenceswhenusingreferencecountingsmartpointers.'>Watch out for cyclic references when using reference counting smart pointers.</a></li>
<li><a href='#C%2B%2BBestPractices-Passsmartpointersas%7B%7Bconst%26%7D%7Dinsteadofbyvalue'>Pass smart pointers as <tt>const &</tt> instead of by value</a></li>
<li><a href='#C%2B%2BBestPractices-Avoidvolatile'>Avoid volatile</a></li>
<li><a href='#C%2B%2BBestPractices-DoNotAllowExceptionsto%22Escape%22Destructors'>Do Not Allow Exceptions to "Escape" Destructors</a></li>
</ul></div>
<h3><a name="C%2B%2BBestPractices-Don%27tuse%7B%7Bstd%3A%3Aautoptr%7D%7D.Use%7B%7Bboost%3A%3Asharedptr%7D%7Dinstead."></a>Don't use <tt>std::auto_ptr</tt>. Use <tt>boost::shared_ptr</tt> instead.</h3>
<p>There are some nuances to <tt>std::auto_ptr</tt> that can be problematic if you're not careful. It's even been deprecated in C++11. As a general rule, we just avoid <tt>std::auto_ptr</tt> to avoid the problems.</p>
<p>See <a href="http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=400" class="external-link" rel="nofollow">this article</a> for more details.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="theme: Confluence; brush: cpp; gutter: false">// use shared_ptr instead of auto_ptr
boost::shared_ptr<Foo> buildFoo()
{
return boost::shared_ptr<Foo>(new Foo);
}</pre>
</div></div>
<h3><a name="C%2B%2BBestPractices-Watchoutforcyclicreferenceswhenusingreferencecountingsmartpointers."></a>Watch out for cyclic references when using reference counting smart pointers.</h3>
<p>When using reference counting pointers (<tt>boost::shared_ptr</tt>, Ice <tt>Ptr</tt> types), avoid cyclic references of objects. These could lead to memory leaks, which (ironically) defeats the purpose of the smart pointers in the first place.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="theme: Confluence; brush: cpp; gutter: false">// avoid cyclic references with reference counting pointers
//
// WARNING!!! Bad code follows
//
class Bar;
class Foo
{
public:
void setBar(const boost::shared_ptr<Bar>& bar) { mBar = bar; }
private:
boost::shared_ptr<Bar> mBar;
};
class Bar
{
public:
void setFoo(const boost::shared_ptr<Foo>& foo) { mFoo = foo; }
private:
boost::shared_ptr<Foo> mFoo; // uh oh; cyclic reference could mean trouble!
};
void leak()
{
boost::shared_ptr<Foo> f(new Foo());
boost::shared_ptr<Bar> b(new Bar());
f->setBar(b);
b->setFoo(f);
// YIKES! f and b have just leaked.
}</pre>
</div></div>
<h3><a name="C%2B%2BBestPractices-Passsmartpointersas%7B%7Bconst%26%7D%7Dinsteadofbyvalue"></a>Pass smart pointers as <tt>const &</tt> instead of by value</h3>
<p>When passing smart pointers (<tt>boost_shared_ptr</tt>, Ice <tt>Ptr</tt> types, Ice <tt>Prx</tt> types) as function parameters, pass them as <tt>const &</tt> instead of pass-by value. This saves on some needless intermediate copies, since the caller should hold their reference to the object for the duration of the call.</p>
<p>But <b>do not</b> store members or local variables as <tt>const &</tt>. This would fail to increment reference counts, so an object may get deleted before its time.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="theme: Confluence; brush: cpp; gutter: false">// pass smart pointers by const reference
// fizzgop a Foo and Bar together
void fizzgop(const boost::shared_ptr<Foo>& foo, const boost::shared_ptr<Bar>& bar)
{
// pretend there's fizzgoping going on here
// WARNING! this is wrong.
const boost::shared_ptr<Bang>& bang = findAppropriateBang(foo, bar);
}</pre>
</div></div>
<h3><a name="C%2B%2BBestPractices-Avoidvolatile"></a>Avoid volatile</h3>
<p>The <tt>volatile</tt> keyword, by its very definition is compiler specific. Its usage could lead to portability problems and is best avoided.</p>
<h3><a name="C%2B%2BBestPractices-DoNotAllowExceptionsto%22Escape%22Destructors"></a>Do Not Allow Exceptions to "Escape" Destructors</h3>
<p>An uncaught exception thrown from a destructor when the stack is unwinding due to a prior exception results in <tt>terminate()</tt>. If a destructor calls code that may throw, it should surround that code in a <tt>try/catch</tt> block.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="theme: Confluence; brush: cpp; gutter: false">Foo::~Foo()
{
try
{
// Do a bunch of stuff that may throw.
}
catch (...)
{
// You can also catch specific exceptions.
}
}</pre>
</div></div>
</div>
<div id="commentsSection" class="wiki-content pageSection">
<div style="float: right;" class="grey">
<a href="https://wiki.asterisk.org/wiki/users/removespacenotification.action?spaceKey=TOP">Stop watching space</a>
<span style="padding: 0px 5px;">|</span>
<a href="https://wiki.asterisk.org/wiki/users/editmyemailsettings.action">Change email notification preferences</a>
</div>
<a href="https://wiki.asterisk.org/wiki/pages/viewpage.action?pageId=9568664">View Online</a>
|
<a href="https://wiki.asterisk.org/wiki/pages/diffpagesbyversion.action?pageId=9568664&revisedVersion=4&originalVersion=3">View Changes</a>
|
<a href="https://wiki.asterisk.org/wiki/pages/viewpage.action?pageId=9568664&showComments=true&showCommentArea=true#addcomment">Add Comment</a>
</div>
</div>
</div>
</div>
</div>
</body>
</html>