SlideShare une entreprise Scribd logo
1  sur  57
Federico Ficarelli
http://www.linkedin.com/in/fficarelli





Chapter 1: Design Issues
Chapter 2: Construction/Destruction/Copying
Chapter 3: Namespaces
Appendix: Tools

Federico Ficarelli, Idiomatic C++

2
Herb Sutter and Andrei Alexandrescu, C++
Coding Standards
 Bjarne Stroustrup’s C++ Style and Technique
FAQ [www.stroustrup.com/bs_faq2.html]
 stackoverflow.com, C++faq tag
 Microsoft Channel 9 [http://channel9.msdn.com/]
 Scott Meyers, Effective C++
 cppreference.com
 Bjarne Stroustrup, The C++ Programming
Language


Federico Ficarelli, Idiomatic C++

3
Design Issues:
Idioms and Best Practices
void foo ()
{
char* ch = new char[100];
if (...)
if (...)
return;
else if (...)
if (...)
else
throw "ERROR";
// This may not be invoked...
delete [] ch;
}
void bar ()
{
lock.acquire();
if (...)
if (...)
return;
else
throw "ERROR";
// This may not be invoked...
lock.release();
}

In order to guarantee resources
release, we need to keep track of:
 natural return;
 return statements;
 exceptions thrown.
Issues:
 code complexity;
 duplicated code (copy and paste);
 forces to catch and re-throw
(even if we aren’t able to handle it);
 error prone.
Federico Ficarelli, Idiomatic C++

5
Exception Safety Rule:
the only code that is guaranteed to be executed after an
exception is thrown are the destructors of objects residing on
the stack.

template <class T>
class AutoDelete
{
public:
AutoDelete (T * p = 0) :
ptr_(p) {}

class ScopedLock
{
public:
ScopedLock (Lock & l) : lock_(l) {
lock_.acquire();
}

~AutoDelete () throw() {
delete ptr_;
}
private:
T *ptr_;
DISALLOW_COPY_AND_ASSIGN(AutoDelete);
};

~ScopedLock () throw () {
lock_.release();
}
private:
Lock& lock_;
DISALLOW_COPY_AND_ASSIGN(ScopedLock);
};
Federico Ficarelli, Idiomatic C++

6
RAII:
every time you need to wrap and manage a resource (memory, file,
lock, etc...) in a class, let the constructor acquire and the destructor
release it: the stack semantics will release the resource when it leaves
the scope.
void foo() {
AutoDelete<X> safe_del(new X());
if (...)
if (...)
return;
// No need to call delete here.
// Destructor will delete memory
}
void bar() {
ScopedLock safe_lock(l);
if (...)
if (...)
throw "ERROR";
// No need to call release here.
// Destructor will release the lock
}
Federico Ficarelli, Idiomatic C++

7
// Da Stroustrup’s C++ FAQ:
class File_handle {
FILE* p;
public:
File_handle(const char* n, const char* a) {
p = fopen(n,a);
if (p==0) throw errno;
}
File_handle(FILE* pp) {
p = pp;
if (p==0) throw errno;
}
~File_handle() { fclose(p); }
operator FILE*() { return p; }
// ...
};

void f(const char* fn) {
File_handle f(fn,"rw");
// use file through f,
// don't care about release
// ...
}

Federico Ficarelli, Idiomatic C++

8
Constructor:
it must acquire the managed resource and, in case of failure,
raise a proper exception. The acquisition process must be RAII
itself (without relying on the destructor).
Destructor:
it starts with a valid and constructed object (guaranteed by
constructor) and must release the resource. It cannot fail.
Single Responsibility Principle:
every class should have a single, clear responsibility and that
responsibility should be entirely encapsulated by the class.
Federico Ficarelli, Idiomatic C++

9




Automatic lifetime, tightly bound to stack
semantics;
each resource type needs a proper resource
holder;
strict ownership, resources cannot be (easily
and cleanly) passed around.

Federico Ficarelli, Idiomatic C++

10
Ownership Semantics:
an object owns a resource when it has the responsibility to release
that resource.

How can we explicitly express ownership in C++?
// Header file
// ...
// AMAZING documentation about
// the following function.
Resource* get_resource();
// ...

struct Resource {
void foo() { /* ... */}
};
Resource* get_resource() {
return new Resource;
// Ownership implicitly transferred to the caller
}

int main (void) {
get_resource()->foo(); // ?
}
Federico Ficarelli, Idiomatic C++

11
Strict ownership, transfer allowed

Strict ownership, transfer not allowed

std::auto_ptr<T>
std::unique_ptr<T>

(C++03)
(C++11)

boost::scoped_ptr<T>
(no std)
const std::auto_ptr<T> (C++03)
std::tr1::scoped_ptr
(C++03)

boost::shared_ptr<T>
(no std)
std::tr1::shared_ptr<T> (TR1)
std::shared_ptr<T>
(C++11)

Shared (multiple) ownership

boost::weak_ptr<T>
std::tr1::weak_ptr<T>
std::weak_ptr<T>

(no std)
(TR1)
(C++11)

Federico Ficarelli, Idiomatic C++

12
Strict Ownership, Transfer Allowed:
the auto_ptr has semantics of strict ownership, meaning that there is only one
auto_ptr instance responsible for the object's lifetime. If an auto_ptr is copied, the
source loses the reference.
#include <memory>
int main() {
T* pt1 = new T;

#include <memory>
int main() {
std::auto_ptr<T> pt( new T );
}
// <-- ~T()

// pass ownership to an auto_ptr
std::auto_ptr<T> pt2( pt1 );
*pt2 = 12;
// same as "*pt1 = 12;
pt2->SomeFunc(); // same as "pt1->SomeFunc();




// use get() to see the pointer value
assert( pt1 == pt2.get() );
// use release() to take back ownership
T* pt3 = pt2.release();
// no owner, no auto-delete!
delete pt3;
}



Same semantics as raw ptr;
when the owner goes out of
scope, raw ptr is destroyed
(operator delete);
we can release ownership
and take back the raw ptr.
Federico Ficarelli, Idiomatic C++

13
int main() {
auto_ptr<T> pt( new T(1) );
pt.reset( new T(2) );// ~T(1), owns T(2)
} // ~T(2)




int main() {
auto_ptr<T> pt1( new T
auto_ptr<T> pt2;
//
pt1->DoSomething(); //
pt2 = pt1;
//
pt2->DoSomething(); //
pt1->DoSomething(); //
} // ~T()

); // pt1 owns
pt2 non-owning
ok
pt1 -> pt2
ok
!!!

Ownership can be explicitly dropped and set
on the fly (reset);
a non-owning auto_ptr has the same
semantics as NULL pointer: never
dereference it (check with operator bool).
Federico Ficarelli, Idiomatic C++

14





No custom deleter, can manage objects
allocated with operator new only;
copying and assigning changes the owner of
a resource, modifying not only the lhs but
also the rhs, which breaks assignment
semantics;
cannot be used in stl
containers.
std::vector< std::auto_ptr<T> > v;
/* ... */

std::sort( v.begin(), v.end() ); // ?

Federico Ficarelli, Idiomatic C++

15
Strict Ownership, Transfer Not Allowed:
the scoped_ptr has semantics of strict ownership, meaning that there is only one
scoped_ptr instance responsible for the object's lifetime. The owning scoped_ptr
cannot be copied, ownership cannot be transferred.







Used to show explicit ownership;
supports custom deleter;
useful for automatic deletion of local objects
or class members (PIMPL, RAII, etc...)
can be “simulated” using the
const auto_ptr Idiom.

const auto_ptr<T> pt1( new T );
auto_ptr<T> pt2( pt1 ); // illegal
auto_ptr<T> pt3;
pt3 = pt1;
// illegal
pt1.release();
// illegal
pt1.reset( new T );
// illegal
Federico Ficarelli, Idiomatic C++

16
Shared Ownership:
the shared_ptr has semantics of multiple ownership, meaning that multiple owning
instances are allowed at a time. The instance is reference counted*: it will be destroyed
only when the last owner is released.






Useful when object’s lifetime is complex and
not tied to a particular scope/object;
supports custom deleter;
can be safely used inside stl containers.

Federico Ficarelli, Idiomatic C++

17
int main() {
typedef std::tr1::shared_ptr<T> sh_ptr;

Reference count semantics

Custom deleter

sh_ptr p1;
{
sh_ptr p2(new T()); // ref = 1
p1=p2; // ref = 2
} // ref = 1
} // ref = 0 -> ~T()

template <typename T>
class ArrayDeleter {
public:
void operator() (T* d) const {
delete [] d;
}
};
std::tr1::shared_ptr<double>
array (new double[256], ArrayDeleter<double>());

Federico Ficarelli, Idiomatic C++

18
template<class T> class decorator {
private:
T * p_;
public:
explicit pointer(T * p): p_(p) {}
shared_ptr<T> operator->() const {
p_->prefix();
return std::tr1::shared_ptr<T>(p_, std::mem_fn(&T::suffix));
}
};

class X {
private:
void prefix();
void suffix();
friend class decorator<X>;
public:
void f();
void g();
};

int main() {
X x;
decorator<X> px(&x);

px->f();
px->g();
}

Federico Ficarelli, Idiomatic C++

19





Expresses «weak» (latent) ownership;
must be casted to shared_ptr before actual
use (no operators);
essential to break reference cycles.
typedef std::tr1::shared_ptr<T> sh_ptr;
typedef std::tr1::weak_ptr<T> wk_ptr;

typedef std::tr1::shared_ptr<T> sh_ptr;
struct T {
sh_ptr other;
};
void test() {
sh_ptr p1
sh_ptr p2
p1->other
p2->other
} // ?

(new T());
(new T());
= p2; // p1 -> p2
= p1; // p2 -> p1

struct T {
wk_ptr other;
};
void test() {
sh_ptr p1 (new T());
sh_ptr p2 (new T());
if( sh_ptr p = p1->other.lock() ) {
p(p2); // p1 -> p2
}
if( sh_ptr p = p2->other.lock() ) {
p(p1); // p2 -> p1
}
} // ?
Federico Ficarelli, Idiomatic C++

20
Resource Return Idiom:
never return raw pointers from within functions; prefer conveying resource ownership
explicitly in the return type.







Makes factory
functions ownership
explicit;
use any type of smart
ptr (depending on your
needs);
improves robustness
dramatically.

// Header file
// ...
// AMAZING documentation about
// the following function.
std::auto_ptr<Resource> get_resource();
// ...
struct Resource {
void foo() { /* ... */}
/* ... */
};

std::auto_ptr<Resource> get_resource() {
return std::auto_ptr<Resource>( new Resource );
// Ownership EXPLICITLY transferred
// to the caller
}
int main (void) {
get_resource()->foo(); // ~Resource()
}
Federico Ficarelli, Idiomatic C++

21
Header files should be written to:
 be self-sufficient;
 be portable;
 minimize dependencies;
 avoid pollution of client’s names search
space.

Federico Ficarelli, Idiomatic C++

22
#ifndef _DATE_H_
#define _DATE_H_

void set_date(int month, int day, int year) {
month_ = month;
day_ = day;
year_ = year;
}

#include <iostream>
#include <math.h>
#include <muslimdate.h>
using namespace std;

inline void Convert(MuslimDate* other) {
// Some heavy work...
// from math.h:
double res = exp(somevalue);
// ...
*other = MuslimDate(/*...*/)
}

namespace calendar {
class Date
{
private:
int month_, day_, year_;

inline int get_month() { return month_; }
inline get_day() { return day_; }
inline get_year() { return year_; }

friend ostream & operator<<
(ostream &os, const Date& d);
};
public:
Date() {
set_date( 1, 1, 1970 );
}
Date(int month, int day, int year) {
set_date(month, day, year);
}
// ...

ostream & operator<<(ostream &os, const Date& date)
{
return os << day_
<< "/"
<< month_ << "/" << year_;
}
} // namespace calendar
#endif // _DATE_H_

Federico Ficarelli, Idiomatic C++

23
// date.h
#ifndef IDIOMATICPP_DATE_H_16032013 // <-#define IDIOMATICPP_DATE_H_16032013
#include <iosfwd> // <--

// ...
// Inline Guard Idiom
#if defined(IDIOMATICCPP_USE_INLINE)
#define INLINE inline
#include <date-inl.h>
#endif

namespace calendar {
} // namespace calendar
class MuslimDate; // <-- Forward
#endif // IDIOMATICPP_DATE_H_16032013
class Date
{
private:
int month_, day_, year_;
friend std::ostream & operator<<
(std::ostream &os, const Date& d);
public:
Date();
Date(int month, int day, int year);
void set_date(int month, int day, int year);
void Convert(MuslimDate* other);
int get_month();
int get_day();
int get_year();
};







Guards: avoid clashes and
reserved identifiers;
prefer forward declarations;
remove unused inclusions;
remove using statements;
be sure that the pure header
is made of declarations only.
Federico Ficarelli, Idiomatic C++

24






Collect all inline
definitions in a separate
header;
beware of C std
headers;
no using statements
(qualify all identifiers);
be sure that the inline
header is made of inline
definitions only.

// date-inl.h
#ifndef IDIOMATICPP_DATE_INL_H_16032013 // <-#define IDIOMATICPP_DATE_INL_H_16032013
#include <muslimdate.h>
#include <cmath> // <-#include <date.h>
INLINE void Date::Convert(MuslimDate* other) {
// Some heavy work...
double res = std::exp(somevalue); // <-// ...
*other = MuslimDate(/*...*/)
}
INLINE int Date::get_month() { return month_; }
INLINE int Date::get_day() { return day_; }
INLINE int Date::get_year() { return year_; }
#endif // IDIOMATICPP_DATE_INL_H_16032013

Federico Ficarelli, Idiomatic C++

25
#include <date.h>
#if !defined(IDIOMATICCPP_USE_INLINE) // <-#define INLINE
#include <date-inl.h>
#endif
#include <iostream>

// ...from date.h:
// ...
// Inline Guard Idiom
#if defined(IDIOMATICCPP_USE_INLINE)
#define INLINE inline
#include <date-inl.h>
#endif
// ...

using namespace std; // <-using namespace calendar;
Date::Date() { set_date( 1, 1, 1970 ); }



Date::Date(int month, int day, int year) {
set_date(month, day, year);
}
void Date::set_date(int month, int day, int year) {
month_ = month;
day_ = day;
year_ = year;
}
ostream & operator<<(ostream &os, const Date& date)
{
return os << day_ << "/"
<< month_ << "/" << year_;
}



Put the Idiom’s flip
side in a single
implementation file;
inlining can be
controlled by a proper
macro definition.
Federico Ficarelli, Idiomatic C++

26




The vast majority of header-related idioms
care about decoupling;
the main goal is to reduce dependencies and
build time;
accepted downsides could impact
performance.

Federico Ficarelli, Idiomatic C++

27



Classical OO approach to decoupling;
invokes implementation of an abstraction/class
using runtime polymorphism;

Dependency Inversion Principle:
implementation classes should not depend on each other. Instead, they should
depend on common abstraction represented using an interface class.

Federico Ficarelli, Idiomatic C++

28
// Abstract base class -> Interface
class Exporter {
public:
virtual std::string
toString(Document* doc) = 0;
};
// Concrete interface implementors (Liskov)
class CSVExporter : public Exporter {
public:
std::string toString(Document* doc)
{ /* ... */ }
};
class XMLExporter : public Exporter {
public:
std::string toString(Document* doc)
{ /* ... */ }
};

// Client (Open Close Principle)
class ExportController {
private:
Exporter* m_exporter; // <-public:
void setExporter(Exporter* exporter);
void runExport();
};
void ExportController::runExport() {
Document* currentDocument =
GetCurrentDocument(); // <-- Factory
// (no ctors)
String exportedString =
m_exporter->toString(currentDocument);
String exportFilePath = GetSaveFilePath();
WriteStringToFile(exporterString, exportFilePath);
}

DIP: ExportController (higher level interface) has no
knowledge of any Exporter subclass (lower level interface);
 both depend on abstract Exporter interface (the common
abstraction).


Federico Ficarelli, Idiomatic C++

29





The language makes private members
inaccessible but not invisible;
idiom meant to completely decouple
interface (and clients) from implementation;
implements a true compilation firewall;
consider carefully the advantages (build
time, insulation) and downsides (extra
indirection level).
Federico Ficarelli, Idiomatic C++

30
// myclass.h:
class MyClass {
private:
struct MyClassPIMPL;
MyClassPIMPL* pimpl_;

// myclass.cpp:
#include "myclass.h"
// Forward
// Handle

public:
Handle();
Handle(const Handle&);
Handle& operator=(const Handle&);
~Handle();
// Other operations...
};

// myclass.h:
class MyClass {
private:
struct MyClassPIMPL;
shared_ptr<MyClassPIMPL> pimpl_;
public:
// ...
};

struct MyClass::MyClassPIMPL {
int a, b;
};

MyClass::MyClass()
: pimpl_(new MyClassPIMPL()) {
// do nothing
}
MyClass::MyClass(const MyClass& other)
: pimpl_(new MyClassPIMPL(*(other.pimpl_))) {
// do nothing
}
MyClass& MyClass::operator=(const MyClass &other) {
delete pimpl_;
*pimpl_ = *(other.pimpl_);
return *this;
}
MyClass::~MyClass() {
delete pimpl_;
}
Federico Ficarelli, Idiomatic C++

31
When implementing functionalities, the common belief
is that OO prefers members.
Function Placement:
when implementing new functionalities, prefer non-member non-friend
functions.





Improves encapsulation by minimizing
dependencies: the function cannot depend nonpublic members (“Don’t give away your
internals”);
breaks apart monolithic classes to liberate
separable functionalities, reducing coupling.
Federico Ficarelli, Idiomatic C++

32
class NetworkBuffer {
public:
bool empty() {
return
this->device->get_packets_count() == 0;
}
/* ... */
};
class List {
public:
bool empty() {
return
this->length == 0;
}
/* ... */
};

class NetworkBuffer {
public:
size_t size() {
return
this->device->get_packets_count();
}
/* ... */
};
class List {
public:
size_t size() {
return this->length;
}
/* ... */
};
template<class T>
bool empty( const T& s )
{
return s.size() == 0;
}

Federico Ficarelli, Idiomatic C++

33
if (f needs to be virtual)
make f a member function of C;
else if (f is operator>> or operator<<)
{
make f a non-member function;
if (f needs access to non-public members of C)
make f a friend of C;
}
else if (f needs type conversions on its left-most
argument)
{
make f a non-member function;
if (f needs access to non-public members of C)
make f a friend of C;
}
else if (f can be implemented via C's public
interface)
make f a non-member function;
else
make f a member function of C;

Functions: the Meyer’s Algorithm [Effective C++]
Federico Ficarelli, Idiomatic C++

34
1.

2.
3.
4.
5.
6.

Ensure resources are owned by objects. Use
explicit RAII and smart pointers to expose
ownership and enforce exception safety.
Give one entity one cohesive responsibility.
Keep your header files clean, don’t harm
clients (nor yourself).
PIMPL and DIP judiciously.
Don’t optimize prematurely:
correctness, simplicity and clarity come first.
Don’t pessimize prematurely.
Federico Ficarelli, Idiomatic C++

35
Construction/Destruction/Copying
Design and implementation of the Big Four:
 default construction,
 copy construction;
 copy assignment,
 destruction.
Pay attention:
 compiler can generate them for you;
 the language treats classes with value
semantics by deafult.
Federico Ficarelli, Idiomatic C++

37
Failing Constructors:
“You should throw an exception from a constructor whenever you cannot
properly initialize (construct) an object. There is no really satisfactory alternative
to exiting a constructor by a throw”. [Stroustrup’s C++ FAQ]




Throwing from within a constructor is the
most safe and widespread technique;
the «init method» technique is unsafe and
breaks RAII and all the idioms discussed in
this chapter.
Federico Ficarelli, Idiomatic C++

38
Warning: the constructor itself must be
exception-safe (without relying on destructor).
class T {
public:
T(std::size_t len = 0) :
array( new int[len] ),
buffer( new char[len]) {} // <-- ?
// Destructor (omitted)
private:
int* array;
char* buffer;
};

class T {
public:
T(std::size_t len = 0) :
array( new int[len] ),
buffer( new char[len]) {} // <-- ?
// Destructor (omitted)
private:
std::shared_array<int> array;
std::shared_array<char> buffer;
};

Federico Ficarelli, Idiomatic C++

39
Rule Of Three:
if you need to explicitly declare either the destructor, copy constructor or copy
assignment operator yourself, you probably need to explicitly declare all three
of them.
class dumb_string {
public:
dumb_string(std::size_t size = 0) : // conversion/default
mSize(size),
mArray(mSize ? new char[mSize]() : 0) {}
dumb_string(const dumb_string& other) : // copy
mSize(other.mSize),
mArray(mSize ? new char[mSize]() : 0) {
std::copy(other.mArray, other.mArray + mSize, mArray);
}
virtual ~dumb_string() { // destructor
delete [] mArray;
}
private:
std::size_t mSize;
char* mArray;
};

int main() {
dumb_string a(10);
dumb_string b(a);
dumb_string c;
c = a; // ?
}
Federico Ficarelli, Idiomatic C++

40
Disable Copying:
whenever it makes sense, explicitly disable copy by construction and by
assignment. This prevents the language from treating types with
unwanted/erratic value semantics.

#define DISALLOW_COPY_AND_ASSIGN(TypeName) 
TypeName(const TypeName&);

void operator=(const TypeName&)
// ...
private:
DISALLOW_COPY_AND_ASSIGN(T);
};

template <class T>
class NonCopyable
{
protected:
NonCopyable () {}
~NonCopyable () {} // Protected non-virtual
private:
NonCopyable (const NonCopyable &);
NonCopyable & operator = (const NonCopyable &);
};
class CantCopy : private NonCopyable <CantCopy> {};

CRTP Mixin: enables Empty Base Optimization
Federico Ficarelli, Idiomatic C++

41




We need to implement the copy-assignment
operator in order to have a correct value
semantics;
operator= is much more hard to implement
in a robust way than the copy constructor:
 must handle an already constructed object;
 in case of failure, it must leave the object in the

previous consistent state (rollback).
The copy-assignment operator must be transactional.
Federico Ficarelli, Idiomatic C++

42
dumb_string& operator=(const dumb_string& other)
{
if (this != &other) // <-{
// Tear down object’s state…
delete [] mArray; // <-mArray = 0; // avoid double-deletion in case of RAII
// ...and setup the new one...
mSize = other.mSize; // <-mArray = mSize ? new int[mSize] : 0;
std::copy(other.mArray, other.mArray + mSize, mArray); // <-}
return *this;
}

Issues:
 self assignment test: a symptom of non-robust
implementation; usually very rare (performance
waste);
 non exception-safe.
Federico Ficarelli, Idiomatic C++

43
dumb_string& operator=(const dumb_string& other)
{
if (this != &pOther) // <-{
// setup the new data ready before we teardown the old
std::size_t newSize = other.mSize;
int* newArray = newSize ? new int[newSize]() : 0; // <-std::copy(other.mArray, other.mArray + newSize, newArray);

// replace the old data (all are nothrow)
delete [] mArray;
mSize = newSize;
mArray = newArray;
}
return *this;
}

Issues:
 code duplication.
Federico Ficarelli, Idiomatic C++

44
friend void swap(dumb_string& first, dumb_string& second) throw()
{
std::swap(first.mSize, second.mSize); // throw()
std::swap(first.mArray, second.mArray); // throw()
}
dumb_string& operator=(const dumb_string& other)
{
dumb_array temp(other);
swap(*this, temp); // <-return *this;
}

dumb_string& operator=(dumb_string other) // <-{
swap(*this, other); // <-return *this;
}

Pass by Value: enables Copy Elision Optimization

Rule-of-Three-and-a-half:
whenever it makes sense, provide a no-fail swap.

Enables strong exception-guarantee (especially the RVO
version);
 enables type to be used with a large number of idioms.


Federico Ficarelli, Idiomatic C++

45
Foundations Never Fail:
everything that destructor, deallocation (e.g.: operator delete)
and swap functions attempt shall succeed: never allow an error to be
reported from within them. They are the foundation of transactional
programming: without their resilience, no-fail rollback is impossible to
implement.

Federico Ficarelli, Idiomatic C++

46
When writing a class, consider:
 Rule-of-three(and-a-half) to obtain correct
and robust value semantics for complex
types;
 «None-of-three» for POD/aggregates (let the
compiler generate them for you);
 explicitly disable copy-construction and copy
assignment.
Federico Ficarelli, Idiomatic C++

47
Namespaces
Interface Principle:
for a class T, all functions (including non-member) that both "mention" T
and are "supplied with" T in the same namespace are logically part of
T, because they form part of T's interface.



The language is explicitly designed to enforce
the Interface Principle, ADL/Koenig Lookup
was added for this reason.
Federico Ficarelli, Idiomatic C++

49


Only occurs if the normal lookup of an unqualified
name fails to find a matching class member
function.

“The set of declarations [...] considered for resolution of the
function name is the union of the declarations found by normal
lookup with the declarations found by looking in the set of
namespaces associated with the types of the function
arguments”. [C++03, 3.4.2]
// using namespace std;
std::cout << "hello" << std::endl;

Federico Ficarelli, Idiomatic C++

50
namespace type {
class T {
public:
void f();
};
}
namespace ops {
T operator+( const T&, const T& );
}
int main() {
// using ops::operator+;
type::T a, b;
a.f();
type::T c = ops::operator+(a, b);
}

namespace ns {

class T {
public:
void f();
};
T operator+( const T&, const T& );
}

int main() {
ns::T a, b;
a.f();
ns::T c = a + b;
}

Interface Principle, corollary:
keep a type and its non-member function interfaces in the same namespace.

Federico Ficarelli, Idiomatic C++

51
#include <vector>
namespace N {
struct X {};
template <typename T> int* operator+( T, unsigned )
{ /* do something */ }
}
int main() {
std::vector<N::X> v(5);
v[0]; // <-- v.begin() + 0
}

Depending on std implementation, ADL may
choose:
 std::operator+
 N::operator+ (pulled in the name search by
vector<N::X>)
Federico Ficarelli, Idiomatic C++

52
«Dual» Interface Principle:
avoid putting non-member functions that are not part of the interface of
a type T into the same namespace as T, and especially never put
templated functions or operators into the same namespace as a userdefined type.

Help prevent name-lookup accidents: protect
types from unwanted ADL.

Federico Ficarelli, Idiomatic C++

53
// f1.h
namespace A {
int f(double);
}
// g.h
namespace B {
using A::f;
void g();
}
// f2.h
namespace A {
int f(int);
}

Beware: B::g resolution (and
semantics) depends on the
headers inclusion order.

Namespace Using Principle:

// g.cpp
B::g() {
f(1); // <-- ?
}

avoid putting using namespace directives before any inclusion
directive. Since the inclusion ordering is out of implementor’s control and
depends on client’s implementation, never put using namespace
directives inside header files.
Federico Ficarelli, Idiomatic C++

54
Tools






Clang Static Analyzer
Mozilla dehydra
vera++
cppcheck
Google cpplint

Federico Ficarelli, Idiomatic C++

56
Idiomatic C++

Contenu connexe

Tendances

[C++] The Curiously Recurring Template Pattern: Static Polymorphsim and Expre...
[C++] The Curiously Recurring Template Pattern: Static Polymorphsim and Expre...[C++] The Curiously Recurring Template Pattern: Static Polymorphsim and Expre...
[C++] The Curiously Recurring Template Pattern: Static Polymorphsim and Expre...Francesco Casalegno
 
Scala is java8.next()
Scala is java8.next()Scala is java8.next()
Scala is java8.next()daewon jeong
 
Fun with Lambdas: C++14 Style (part 1)
Fun with Lambdas: C++14 Style (part 1)Fun with Lambdas: C++14 Style (part 1)
Fun with Lambdas: C++14 Style (part 1)Sumant Tambe
 
C++17 introduction - Meetup @EtixLabs
C++17 introduction - Meetup @EtixLabsC++17 introduction - Meetup @EtixLabs
C++17 introduction - Meetup @EtixLabsStephane Gleizes
 
C++11 concurrency
C++11 concurrencyC++11 concurrency
C++11 concurrencyxu liwei
 
Csharp In Detail Part2
Csharp In Detail Part2Csharp In Detail Part2
Csharp In Detail Part2Mohamed Krar
 
C++11: Rvalue References, Move Semantics, Perfect Forwarding
C++11: Rvalue References, Move Semantics, Perfect ForwardingC++11: Rvalue References, Move Semantics, Perfect Forwarding
C++11: Rvalue References, Move Semantics, Perfect ForwardingFrancesco Casalegno
 
Functional programming ii
Functional programming iiFunctional programming ii
Functional programming iiPrashant Kalkar
 
Fun with Lambdas: C++14 Style (part 2)
Fun with Lambdas: C++14 Style (part 2)Fun with Lambdas: C++14 Style (part 2)
Fun with Lambdas: C++14 Style (part 2)Sumant Tambe
 
Paradigmas de Linguagens de Programacao - Aula #4
Paradigmas de Linguagens de Programacao - Aula #4Paradigmas de Linguagens de Programacao - Aula #4
Paradigmas de Linguagens de Programacao - Aula #4Ismar Silveira
 
Replace OutputIterator and Extend Range
Replace OutputIterator and Extend RangeReplace OutputIterator and Extend Range
Replace OutputIterator and Extend RangeAkira Takahashi
 
Modern c++ (C++ 11/14)
Modern c++ (C++ 11/14)Modern c++ (C++ 11/14)
Modern c++ (C++ 11/14)Geeks Anonymes
 

Tendances (20)

Smart pointers
Smart pointersSmart pointers
Smart pointers
 
Summary of C++17 features
Summary of C++17 featuresSummary of C++17 features
Summary of C++17 features
 
C++11
C++11C++11
C++11
 
Smart Pointers in C++
Smart Pointers in C++Smart Pointers in C++
Smart Pointers in C++
 
[C++] The Curiously Recurring Template Pattern: Static Polymorphsim and Expre...
[C++] The Curiously Recurring Template Pattern: Static Polymorphsim and Expre...[C++] The Curiously Recurring Template Pattern: Static Polymorphsim and Expre...
[C++] The Curiously Recurring Template Pattern: Static Polymorphsim and Expre...
 
Scala is java8.next()
Scala is java8.next()Scala is java8.next()
Scala is java8.next()
 
Fun with Lambdas: C++14 Style (part 1)
Fun with Lambdas: C++14 Style (part 1)Fun with Lambdas: C++14 Style (part 1)
Fun with Lambdas: C++14 Style (part 1)
 
What's New in C++ 11?
What's New in C++ 11?What's New in C++ 11?
What's New in C++ 11?
 
C++17 introduction - Meetup @EtixLabs
C++17 introduction - Meetup @EtixLabsC++17 introduction - Meetup @EtixLabs
C++17 introduction - Meetup @EtixLabs
 
C++11 concurrency
C++11 concurrencyC++11 concurrency
C++11 concurrency
 
Modern C++
Modern C++Modern C++
Modern C++
 
Csharp In Detail Part2
Csharp In Detail Part2Csharp In Detail Part2
Csharp In Detail Part2
 
C++11: Rvalue References, Move Semantics, Perfect Forwarding
C++11: Rvalue References, Move Semantics, Perfect ForwardingC++11: Rvalue References, Move Semantics, Perfect Forwarding
C++11: Rvalue References, Move Semantics, Perfect Forwarding
 
Functional programming
Functional programmingFunctional programming
Functional programming
 
Functional programming ii
Functional programming iiFunctional programming ii
Functional programming ii
 
Java Generics
Java GenericsJava Generics
Java Generics
 
Fun with Lambdas: C++14 Style (part 2)
Fun with Lambdas: C++14 Style (part 2)Fun with Lambdas: C++14 Style (part 2)
Fun with Lambdas: C++14 Style (part 2)
 
Paradigmas de Linguagens de Programacao - Aula #4
Paradigmas de Linguagens de Programacao - Aula #4Paradigmas de Linguagens de Programacao - Aula #4
Paradigmas de Linguagens de Programacao - Aula #4
 
Replace OutputIterator and Extend Range
Replace OutputIterator and Extend RangeReplace OutputIterator and Extend Range
Replace OutputIterator and Extend Range
 
Modern c++ (C++ 11/14)
Modern c++ (C++ 11/14)Modern c++ (C++ 11/14)
Modern c++ (C++ 11/14)
 

En vedette

Improving The Quality of Existing Software
Improving The Quality of Existing SoftwareImproving The Quality of Existing Software
Improving The Quality of Existing SoftwareSteven Smith
 
Operator overloading
Operator overloadingOperator overloading
Operator overloadingfarhan amjad
 
C++ Advanced
C++ AdvancedC++ Advanced
C++ AdvancedVivek Das
 
Bjarne Stroustrup - The Essence of C++: With Examples in C++84, C++98, C++11,...
Bjarne Stroustrup - The Essence of C++: With Examples in C++84, C++98, C++11,...Bjarne Stroustrup - The Essence of C++: With Examples in C++84, C++98, C++11,...
Bjarne Stroustrup - The Essence of C++: With Examples in C++84, C++98, C++11,...Complement Verb
 
An Introduction to Part of C++ STL
An Introduction to Part of C++ STLAn Introduction to Part of C++ STL
An Introduction to Part of C++ STL乐群 陈
 
Solid principles of oo design
Solid principles of oo designSolid principles of oo design
Solid principles of oo designConfiz
 
Programming In C++
Programming In C++ Programming In C++
Programming In C++ shammi mehra
 
Exception handling and templates
Exception handling and templatesException handling and templates
Exception handling and templatesfarhan amjad
 
Inheritance, polymorphisam, abstract classes and composition)
Inheritance, polymorphisam, abstract classes and composition)Inheritance, polymorphisam, abstract classes and composition)
Inheritance, polymorphisam, abstract classes and composition)farhan amjad
 
Building Embedded Linux
Building Embedded LinuxBuilding Embedded Linux
Building Embedded LinuxSherif Mousa
 
Abstract Base Class and Polymorphism in C++
Abstract Base Class and Polymorphism in C++Abstract Base Class and Polymorphism in C++
Abstract Base Class and Polymorphism in C++Liju Thomas
 
Keys to Continuous Delivery Success - Mark Warren, Product Director, Perforc...
Keys to Continuous  Delivery Success - Mark Warren, Product Director, Perforc...Keys to Continuous  Delivery Success - Mark Warren, Product Director, Perforc...
Keys to Continuous Delivery Success - Mark Warren, Product Director, Perforc...Perforce
 
Building Embedded Linux Full Tutorial for ARM
Building Embedded Linux Full Tutorial for ARMBuilding Embedded Linux Full Tutorial for ARM
Building Embedded Linux Full Tutorial for ARMSherif Mousa
 

En vedette (19)

Distributed Systems Design
Distributed Systems DesignDistributed Systems Design
Distributed Systems Design
 
Improving The Quality of Existing Software
Improving The Quality of Existing SoftwareImproving The Quality of Existing Software
Improving The Quality of Existing Software
 
Operator overloading
Operator overloadingOperator overloading
Operator overloading
 
C++ Advanced
C++ AdvancedC++ Advanced
C++ Advanced
 
Web Service Basics and NWS Setup
Web Service  Basics and NWS SetupWeb Service  Basics and NWS Setup
Web Service Basics and NWS Setup
 
Bjarne Stroustrup - The Essence of C++: With Examples in C++84, C++98, C++11,...
Bjarne Stroustrup - The Essence of C++: With Examples in C++84, C++98, C++11,...Bjarne Stroustrup - The Essence of C++: With Examples in C++84, C++98, C++11,...
Bjarne Stroustrup - The Essence of C++: With Examples in C++84, C++98, C++11,...
 
Operator overloading
Operator overloading Operator overloading
Operator overloading
 
An Introduction to Part of C++ STL
An Introduction to Part of C++ STLAn Introduction to Part of C++ STL
An Introduction to Part of C++ STL
 
Solid principles of oo design
Solid principles of oo designSolid principles of oo design
Solid principles of oo design
 
SOLID Principles part 2
SOLID Principles part 2SOLID Principles part 2
SOLID Principles part 2
 
Programming In C++
Programming In C++ Programming In C++
Programming In C++
 
SOLID Principles part 1
SOLID Principles part 1SOLID Principles part 1
SOLID Principles part 1
 
Exception handling and templates
Exception handling and templatesException handling and templates
Exception handling and templates
 
Inheritance, polymorphisam, abstract classes and composition)
Inheritance, polymorphisam, abstract classes and composition)Inheritance, polymorphisam, abstract classes and composition)
Inheritance, polymorphisam, abstract classes and composition)
 
Memory Management In C++
Memory Management In C++Memory Management In C++
Memory Management In C++
 
Building Embedded Linux
Building Embedded LinuxBuilding Embedded Linux
Building Embedded Linux
 
Abstract Base Class and Polymorphism in C++
Abstract Base Class and Polymorphism in C++Abstract Base Class and Polymorphism in C++
Abstract Base Class and Polymorphism in C++
 
Keys to Continuous Delivery Success - Mark Warren, Product Director, Perforc...
Keys to Continuous  Delivery Success - Mark Warren, Product Director, Perforc...Keys to Continuous  Delivery Success - Mark Warren, Product Director, Perforc...
Keys to Continuous Delivery Success - Mark Warren, Product Director, Perforc...
 
Building Embedded Linux Full Tutorial for ARM
Building Embedded Linux Full Tutorial for ARMBuilding Embedded Linux Full Tutorial for ARM
Building Embedded Linux Full Tutorial for ARM
 

Similaire à Idiomatic C++

The Rust Programming Language: an Overview
The Rust Programming Language: an OverviewThe Rust Programming Language: an Overview
The Rust Programming Language: an OverviewRoberto Casadei
 
개발 과정 최적화 하기 내부툴로 더욱 강력한 개발하기 Stephen kennedy _(11시40분_103호)
개발 과정 최적화 하기 내부툴로 더욱 강력한 개발하기 Stephen kennedy _(11시40분_103호)개발 과정 최적화 하기 내부툴로 더욱 강력한 개발하기 Stephen kennedy _(11시40분_103호)
개발 과정 최적화 하기 내부툴로 더욱 강력한 개발하기 Stephen kennedy _(11시40분_103호)changehee lee
 
#OOP_D_ITS - 2nd - C++ Getting Started
#OOP_D_ITS - 2nd - C++ Getting Started#OOP_D_ITS - 2nd - C++ Getting Started
#OOP_D_ITS - 2nd - C++ Getting StartedHadziq Fabroyir
 
#OOP_D_ITS - 3rd - Pointer And References
#OOP_D_ITS - 3rd - Pointer And References#OOP_D_ITS - 3rd - Pointer And References
#OOP_D_ITS - 3rd - Pointer And ReferencesHadziq Fabroyir
 
Welcome to Modern C++
Welcome to Modern C++Welcome to Modern C++
Welcome to Modern C++Seok-joon Yun
 
Cbse question-paper-computer-science-2009
Cbse question-paper-computer-science-2009Cbse question-paper-computer-science-2009
Cbse question-paper-computer-science-2009Deepak Singh
 
How to Adopt Modern C++17 into Your C++ Code
How to Adopt Modern C++17 into Your C++ CodeHow to Adopt Modern C++17 into Your C++ Code
How to Adopt Modern C++17 into Your C++ CodeMicrosoft Tech Community
 
How to Adopt Modern C++17 into Your C++ Code
How to Adopt Modern C++17 into Your C++ CodeHow to Adopt Modern C++17 into Your C++ Code
How to Adopt Modern C++17 into Your C++ CodeMicrosoft Tech Community
 
D vs OWKN Language at LLnagoya
D vs OWKN Language at LLnagoyaD vs OWKN Language at LLnagoya
D vs OWKN Language at LLnagoyaN Masahiro
 
#OOP_D_ITS - 4th - C++ Oop And Class Structure
#OOP_D_ITS - 4th - C++ Oop And Class Structure#OOP_D_ITS - 4th - C++ Oop And Class Structure
#OOP_D_ITS - 4th - C++ Oop And Class StructureHadziq Fabroyir
 
Computer science-2010-cbse-question-paper
Computer science-2010-cbse-question-paperComputer science-2010-cbse-question-paper
Computer science-2010-cbse-question-paperDeepak Singh
 
C cheat sheet for varsity (extreme edition)
C cheat sheet for varsity (extreme edition)C cheat sheet for varsity (extreme edition)
C cheat sheet for varsity (extreme edition)Saifur Rahman
 
Lies Told By The Kotlin Compiler
Lies Told By The Kotlin CompilerLies Told By The Kotlin Compiler
Lies Told By The Kotlin CompilerGarth Gilmour
 
Vladymyr Bahrii Understanding polymorphism in C++ 16.11.17
Vladymyr Bahrii Understanding polymorphism in C++ 16.11.17Vladymyr Bahrii Understanding polymorphism in C++ 16.11.17
Vladymyr Bahrii Understanding polymorphism in C++ 16.11.17LogeekNightUkraine
 
Using the sample C Programming Language code in Section 4-2 (Lexical A.pdf
Using the sample C Programming Language code in Section 4-2 (Lexical A.pdfUsing the sample C Programming Language code in Section 4-2 (Lexical A.pdf
Using the sample C Programming Language code in Section 4-2 (Lexical A.pdfOwenPBLRobertsv
 

Similaire à Idiomatic C++ (20)

The Rust Programming Language: an Overview
The Rust Programming Language: an OverviewThe Rust Programming Language: an Overview
The Rust Programming Language: an Overview
 
개발 과정 최적화 하기 내부툴로 더욱 강력한 개발하기 Stephen kennedy _(11시40분_103호)
개발 과정 최적화 하기 내부툴로 더욱 강력한 개발하기 Stephen kennedy _(11시40분_103호)개발 과정 최적화 하기 내부툴로 더욱 강력한 개발하기 Stephen kennedy _(11시40분_103호)
개발 과정 최적화 하기 내부툴로 더욱 강력한 개발하기 Stephen kennedy _(11시40분_103호)
 
#OOP_D_ITS - 2nd - C++ Getting Started
#OOP_D_ITS - 2nd - C++ Getting Started#OOP_D_ITS - 2nd - C++ Getting Started
#OOP_D_ITS - 2nd - C++ Getting Started
 
#OOP_D_ITS - 3rd - Pointer And References
#OOP_D_ITS - 3rd - Pointer And References#OOP_D_ITS - 3rd - Pointer And References
#OOP_D_ITS - 3rd - Pointer And References
 
Welcome to Modern C++
Welcome to Modern C++Welcome to Modern C++
Welcome to Modern C++
 
Vcs15
Vcs15Vcs15
Vcs15
 
Cbse question-paper-computer-science-2009
Cbse question-paper-computer-science-2009Cbse question-paper-computer-science-2009
Cbse question-paper-computer-science-2009
 
How to Adopt Modern C++17 into Your C++ Code
How to Adopt Modern C++17 into Your C++ CodeHow to Adopt Modern C++17 into Your C++ Code
How to Adopt Modern C++17 into Your C++ Code
 
How to Adopt Modern C++17 into Your C++ Code
How to Adopt Modern C++17 into Your C++ CodeHow to Adopt Modern C++17 into Your C++ Code
How to Adopt Modern C++17 into Your C++ Code
 
D vs OWKN Language at LLnagoya
D vs OWKN Language at LLnagoyaD vs OWKN Language at LLnagoya
D vs OWKN Language at LLnagoya
 
#OOP_D_ITS - 4th - C++ Oop And Class Structure
#OOP_D_ITS - 4th - C++ Oop And Class Structure#OOP_D_ITS - 4th - C++ Oop And Class Structure
#OOP_D_ITS - 4th - C++ Oop And Class Structure
 
Computer science-2010-cbse-question-paper
Computer science-2010-cbse-question-paperComputer science-2010-cbse-question-paper
Computer science-2010-cbse-question-paper
 
Xiicsmonth
XiicsmonthXiicsmonth
Xiicsmonth
 
C cheat sheet for varsity (extreme edition)
C cheat sheet for varsity (extreme edition)C cheat sheet for varsity (extreme edition)
C cheat sheet for varsity (extreme edition)
 
Lies Told By The Kotlin Compiler
Lies Told By The Kotlin CompilerLies Told By The Kotlin Compiler
Lies Told By The Kotlin Compiler
 
Rust vs C++
Rust vs C++Rust vs C++
Rust vs C++
 
Vladymyr Bahrii Understanding polymorphism in C++ 16.11.17
Vladymyr Bahrii Understanding polymorphism in C++ 16.11.17Vladymyr Bahrii Understanding polymorphism in C++ 16.11.17
Vladymyr Bahrii Understanding polymorphism in C++ 16.11.17
 
Using the sample C Programming Language code in Section 4-2 (Lexical A.pdf
Using the sample C Programming Language code in Section 4-2 (Lexical A.pdfUsing the sample C Programming Language code in Section 4-2 (Lexical A.pdf
Using the sample C Programming Language code in Section 4-2 (Lexical A.pdf
 
C tutorial
C tutorialC tutorial
C tutorial
 
C tutorial
C tutorialC tutorial
C tutorial
 

Dernier

How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?IES VE
 
Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Adtran
 
Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024SkyPlanner
 
UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8DianaGray10
 
Empowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership BlueprintEmpowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership BlueprintMahmoud Rabie
 
Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024D Cloud Solutions
 
Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Commit University
 
Comparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioComparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioChristian Posta
 
Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfAijun Zhang
 
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Will Schroeder
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1DianaGray10
 
Bird eye's view on Camunda open source ecosystem
Bird eye's view on Camunda open source ecosystemBird eye's view on Camunda open source ecosystem
Bird eye's view on Camunda open source ecosystemAsko Soukka
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesDavid Newbury
 
VoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXVoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXTarek Kalaji
 
Introduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptxIntroduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptxMatsuo Lab
 
COMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a WebsiteCOMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a Websitedgelyza
 
9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding TeamAdam Moalla
 
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019IES VE
 

Dernier (20)

How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?
 
Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™
 
20230104 - machine vision
20230104 - machine vision20230104 - machine vision
20230104 - machine vision
 
Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024
 
UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8
 
Empowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership BlueprintEmpowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership Blueprint
 
Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024
 
Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)
 
Comparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioComparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and Istio
 
Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdf
 
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1
 
Bird eye's view on Camunda open source ecosystem
Bird eye's view on Camunda open source ecosystemBird eye's view on Camunda open source ecosystem
Bird eye's view on Camunda open source ecosystem
 
20150722 - AGV
20150722 - AGV20150722 - AGV
20150722 - AGV
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond Ontologies
 
VoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXVoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBX
 
Introduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptxIntroduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptx
 
COMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a WebsiteCOMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a Website
 
9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team
 
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
 

Idiomatic C++

  • 2.     Chapter 1: Design Issues Chapter 2: Construction/Destruction/Copying Chapter 3: Namespaces Appendix: Tools Federico Ficarelli, Idiomatic C++ 2
  • 3. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards  Bjarne Stroustrup’s C++ Style and Technique FAQ [www.stroustrup.com/bs_faq2.html]  stackoverflow.com, C++faq tag  Microsoft Channel 9 [http://channel9.msdn.com/]  Scott Meyers, Effective C++  cppreference.com  Bjarne Stroustrup, The C++ Programming Language  Federico Ficarelli, Idiomatic C++ 3
  • 4. Design Issues: Idioms and Best Practices
  • 5. void foo () { char* ch = new char[100]; if (...) if (...) return; else if (...) if (...) else throw "ERROR"; // This may not be invoked... delete [] ch; } void bar () { lock.acquire(); if (...) if (...) return; else throw "ERROR"; // This may not be invoked... lock.release(); } In order to guarantee resources release, we need to keep track of:  natural return;  return statements;  exceptions thrown. Issues:  code complexity;  duplicated code (copy and paste);  forces to catch and re-throw (even if we aren’t able to handle it);  error prone. Federico Ficarelli, Idiomatic C++ 5
  • 6. Exception Safety Rule: the only code that is guaranteed to be executed after an exception is thrown are the destructors of objects residing on the stack. template <class T> class AutoDelete { public: AutoDelete (T * p = 0) : ptr_(p) {} class ScopedLock { public: ScopedLock (Lock & l) : lock_(l) { lock_.acquire(); } ~AutoDelete () throw() { delete ptr_; } private: T *ptr_; DISALLOW_COPY_AND_ASSIGN(AutoDelete); }; ~ScopedLock () throw () { lock_.release(); } private: Lock& lock_; DISALLOW_COPY_AND_ASSIGN(ScopedLock); }; Federico Ficarelli, Idiomatic C++ 6
  • 7. RAII: every time you need to wrap and manage a resource (memory, file, lock, etc...) in a class, let the constructor acquire and the destructor release it: the stack semantics will release the resource when it leaves the scope. void foo() { AutoDelete<X> safe_del(new X()); if (...) if (...) return; // No need to call delete here. // Destructor will delete memory } void bar() { ScopedLock safe_lock(l); if (...) if (...) throw "ERROR"; // No need to call release here. // Destructor will release the lock } Federico Ficarelli, Idiomatic C++ 7
  • 8. // Da Stroustrup’s C++ FAQ: class File_handle { FILE* p; public: File_handle(const char* n, const char* a) { p = fopen(n,a); if (p==0) throw errno; } File_handle(FILE* pp) { p = pp; if (p==0) throw errno; } ~File_handle() { fclose(p); } operator FILE*() { return p; } // ... }; void f(const char* fn) { File_handle f(fn,"rw"); // use file through f, // don't care about release // ... } Federico Ficarelli, Idiomatic C++ 8
  • 9. Constructor: it must acquire the managed resource and, in case of failure, raise a proper exception. The acquisition process must be RAII itself (without relying on the destructor). Destructor: it starts with a valid and constructed object (guaranteed by constructor) and must release the resource. It cannot fail. Single Responsibility Principle: every class should have a single, clear responsibility and that responsibility should be entirely encapsulated by the class. Federico Ficarelli, Idiomatic C++ 9
  • 10.    Automatic lifetime, tightly bound to stack semantics; each resource type needs a proper resource holder; strict ownership, resources cannot be (easily and cleanly) passed around. Federico Ficarelli, Idiomatic C++ 10
  • 11. Ownership Semantics: an object owns a resource when it has the responsibility to release that resource. How can we explicitly express ownership in C++? // Header file // ... // AMAZING documentation about // the following function. Resource* get_resource(); // ... struct Resource { void foo() { /* ... */} }; Resource* get_resource() { return new Resource; // Ownership implicitly transferred to the caller } int main (void) { get_resource()->foo(); // ? } Federico Ficarelli, Idiomatic C++ 11
  • 12. Strict ownership, transfer allowed Strict ownership, transfer not allowed std::auto_ptr<T> std::unique_ptr<T> (C++03) (C++11) boost::scoped_ptr<T> (no std) const std::auto_ptr<T> (C++03) std::tr1::scoped_ptr (C++03) boost::shared_ptr<T> (no std) std::tr1::shared_ptr<T> (TR1) std::shared_ptr<T> (C++11) Shared (multiple) ownership boost::weak_ptr<T> std::tr1::weak_ptr<T> std::weak_ptr<T> (no std) (TR1) (C++11) Federico Ficarelli, Idiomatic C++ 12
  • 13. Strict Ownership, Transfer Allowed: the auto_ptr has semantics of strict ownership, meaning that there is only one auto_ptr instance responsible for the object's lifetime. If an auto_ptr is copied, the source loses the reference. #include <memory> int main() { T* pt1 = new T; #include <memory> int main() { std::auto_ptr<T> pt( new T ); } // <-- ~T() // pass ownership to an auto_ptr std::auto_ptr<T> pt2( pt1 ); *pt2 = 12; // same as "*pt1 = 12; pt2->SomeFunc(); // same as "pt1->SomeFunc();   // use get() to see the pointer value assert( pt1 == pt2.get() ); // use release() to take back ownership T* pt3 = pt2.release(); // no owner, no auto-delete! delete pt3; }  Same semantics as raw ptr; when the owner goes out of scope, raw ptr is destroyed (operator delete); we can release ownership and take back the raw ptr. Federico Ficarelli, Idiomatic C++ 13
  • 14. int main() { auto_ptr<T> pt( new T(1) ); pt.reset( new T(2) );// ~T(1), owns T(2) } // ~T(2)   int main() { auto_ptr<T> pt1( new T auto_ptr<T> pt2; // pt1->DoSomething(); // pt2 = pt1; // pt2->DoSomething(); // pt1->DoSomething(); // } // ~T() ); // pt1 owns pt2 non-owning ok pt1 -> pt2 ok !!! Ownership can be explicitly dropped and set on the fly (reset); a non-owning auto_ptr has the same semantics as NULL pointer: never dereference it (check with operator bool). Federico Ficarelli, Idiomatic C++ 14
  • 15.    No custom deleter, can manage objects allocated with operator new only; copying and assigning changes the owner of a resource, modifying not only the lhs but also the rhs, which breaks assignment semantics; cannot be used in stl containers. std::vector< std::auto_ptr<T> > v; /* ... */ std::sort( v.begin(), v.end() ); // ? Federico Ficarelli, Idiomatic C++ 15
  • 16. Strict Ownership, Transfer Not Allowed: the scoped_ptr has semantics of strict ownership, meaning that there is only one scoped_ptr instance responsible for the object's lifetime. The owning scoped_ptr cannot be copied, ownership cannot be transferred.     Used to show explicit ownership; supports custom deleter; useful for automatic deletion of local objects or class members (PIMPL, RAII, etc...) can be “simulated” using the const auto_ptr Idiom. const auto_ptr<T> pt1( new T ); auto_ptr<T> pt2( pt1 ); // illegal auto_ptr<T> pt3; pt3 = pt1; // illegal pt1.release(); // illegal pt1.reset( new T ); // illegal Federico Ficarelli, Idiomatic C++ 16
  • 17. Shared Ownership: the shared_ptr has semantics of multiple ownership, meaning that multiple owning instances are allowed at a time. The instance is reference counted*: it will be destroyed only when the last owner is released.    Useful when object’s lifetime is complex and not tied to a particular scope/object; supports custom deleter; can be safely used inside stl containers. Federico Ficarelli, Idiomatic C++ 17
  • 18. int main() { typedef std::tr1::shared_ptr<T> sh_ptr; Reference count semantics Custom deleter sh_ptr p1; { sh_ptr p2(new T()); // ref = 1 p1=p2; // ref = 2 } // ref = 1 } // ref = 0 -> ~T() template <typename T> class ArrayDeleter { public: void operator() (T* d) const { delete [] d; } }; std::tr1::shared_ptr<double> array (new double[256], ArrayDeleter<double>()); Federico Ficarelli, Idiomatic C++ 18
  • 19. template<class T> class decorator { private: T * p_; public: explicit pointer(T * p): p_(p) {} shared_ptr<T> operator->() const { p_->prefix(); return std::tr1::shared_ptr<T>(p_, std::mem_fn(&T::suffix)); } }; class X { private: void prefix(); void suffix(); friend class decorator<X>; public: void f(); void g(); }; int main() { X x; decorator<X> px(&x); px->f(); px->g(); } Federico Ficarelli, Idiomatic C++ 19
  • 20.    Expresses «weak» (latent) ownership; must be casted to shared_ptr before actual use (no operators); essential to break reference cycles. typedef std::tr1::shared_ptr<T> sh_ptr; typedef std::tr1::weak_ptr<T> wk_ptr; typedef std::tr1::shared_ptr<T> sh_ptr; struct T { sh_ptr other; }; void test() { sh_ptr p1 sh_ptr p2 p1->other p2->other } // ? (new T()); (new T()); = p2; // p1 -> p2 = p1; // p2 -> p1 struct T { wk_ptr other; }; void test() { sh_ptr p1 (new T()); sh_ptr p2 (new T()); if( sh_ptr p = p1->other.lock() ) { p(p2); // p1 -> p2 } if( sh_ptr p = p2->other.lock() ) { p(p1); // p2 -> p1 } } // ? Federico Ficarelli, Idiomatic C++ 20
  • 21. Resource Return Idiom: never return raw pointers from within functions; prefer conveying resource ownership explicitly in the return type.    Makes factory functions ownership explicit; use any type of smart ptr (depending on your needs); improves robustness dramatically. // Header file // ... // AMAZING documentation about // the following function. std::auto_ptr<Resource> get_resource(); // ... struct Resource { void foo() { /* ... */} /* ... */ }; std::auto_ptr<Resource> get_resource() { return std::auto_ptr<Resource>( new Resource ); // Ownership EXPLICITLY transferred // to the caller } int main (void) { get_resource()->foo(); // ~Resource() } Federico Ficarelli, Idiomatic C++ 21
  • 22. Header files should be written to:  be self-sufficient;  be portable;  minimize dependencies;  avoid pollution of client’s names search space. Federico Ficarelli, Idiomatic C++ 22
  • 23. #ifndef _DATE_H_ #define _DATE_H_ void set_date(int month, int day, int year) { month_ = month; day_ = day; year_ = year; } #include <iostream> #include <math.h> #include <muslimdate.h> using namespace std; inline void Convert(MuslimDate* other) { // Some heavy work... // from math.h: double res = exp(somevalue); // ... *other = MuslimDate(/*...*/) } namespace calendar { class Date { private: int month_, day_, year_; inline int get_month() { return month_; } inline get_day() { return day_; } inline get_year() { return year_; } friend ostream & operator<< (ostream &os, const Date& d); }; public: Date() { set_date( 1, 1, 1970 ); } Date(int month, int day, int year) { set_date(month, day, year); } // ... ostream & operator<<(ostream &os, const Date& date) { return os << day_ << "/" << month_ << "/" << year_; } } // namespace calendar #endif // _DATE_H_ Federico Ficarelli, Idiomatic C++ 23
  • 24. // date.h #ifndef IDIOMATICPP_DATE_H_16032013 // <-#define IDIOMATICPP_DATE_H_16032013 #include <iosfwd> // <-- // ... // Inline Guard Idiom #if defined(IDIOMATICCPP_USE_INLINE) #define INLINE inline #include <date-inl.h> #endif namespace calendar { } // namespace calendar class MuslimDate; // <-- Forward #endif // IDIOMATICPP_DATE_H_16032013 class Date { private: int month_, day_, year_; friend std::ostream & operator<< (std::ostream &os, const Date& d); public: Date(); Date(int month, int day, int year); void set_date(int month, int day, int year); void Convert(MuslimDate* other); int get_month(); int get_day(); int get_year(); };      Guards: avoid clashes and reserved identifiers; prefer forward declarations; remove unused inclusions; remove using statements; be sure that the pure header is made of declarations only. Federico Ficarelli, Idiomatic C++ 24
  • 25.     Collect all inline definitions in a separate header; beware of C std headers; no using statements (qualify all identifiers); be sure that the inline header is made of inline definitions only. // date-inl.h #ifndef IDIOMATICPP_DATE_INL_H_16032013 // <-#define IDIOMATICPP_DATE_INL_H_16032013 #include <muslimdate.h> #include <cmath> // <-#include <date.h> INLINE void Date::Convert(MuslimDate* other) { // Some heavy work... double res = std::exp(somevalue); // <-// ... *other = MuslimDate(/*...*/) } INLINE int Date::get_month() { return month_; } INLINE int Date::get_day() { return day_; } INLINE int Date::get_year() { return year_; } #endif // IDIOMATICPP_DATE_INL_H_16032013 Federico Ficarelli, Idiomatic C++ 25
  • 26. #include <date.h> #if !defined(IDIOMATICCPP_USE_INLINE) // <-#define INLINE #include <date-inl.h> #endif #include <iostream> // ...from date.h: // ... // Inline Guard Idiom #if defined(IDIOMATICCPP_USE_INLINE) #define INLINE inline #include <date-inl.h> #endif // ... using namespace std; // <-using namespace calendar; Date::Date() { set_date( 1, 1, 1970 ); }  Date::Date(int month, int day, int year) { set_date(month, day, year); } void Date::set_date(int month, int day, int year) { month_ = month; day_ = day; year_ = year; } ostream & operator<<(ostream &os, const Date& date) { return os << day_ << "/" << month_ << "/" << year_; }  Put the Idiom’s flip side in a single implementation file; inlining can be controlled by a proper macro definition. Federico Ficarelli, Idiomatic C++ 26
  • 27.    The vast majority of header-related idioms care about decoupling; the main goal is to reduce dependencies and build time; accepted downsides could impact performance. Federico Ficarelli, Idiomatic C++ 27
  • 28.   Classical OO approach to decoupling; invokes implementation of an abstraction/class using runtime polymorphism; Dependency Inversion Principle: implementation classes should not depend on each other. Instead, they should depend on common abstraction represented using an interface class. Federico Ficarelli, Idiomatic C++ 28
  • 29. // Abstract base class -> Interface class Exporter { public: virtual std::string toString(Document* doc) = 0; }; // Concrete interface implementors (Liskov) class CSVExporter : public Exporter { public: std::string toString(Document* doc) { /* ... */ } }; class XMLExporter : public Exporter { public: std::string toString(Document* doc) { /* ... */ } }; // Client (Open Close Principle) class ExportController { private: Exporter* m_exporter; // <-public: void setExporter(Exporter* exporter); void runExport(); }; void ExportController::runExport() { Document* currentDocument = GetCurrentDocument(); // <-- Factory // (no ctors) String exportedString = m_exporter->toString(currentDocument); String exportFilePath = GetSaveFilePath(); WriteStringToFile(exporterString, exportFilePath); } DIP: ExportController (higher level interface) has no knowledge of any Exporter subclass (lower level interface);  both depend on abstract Exporter interface (the common abstraction).  Federico Ficarelli, Idiomatic C++ 29
  • 30.     The language makes private members inaccessible but not invisible; idiom meant to completely decouple interface (and clients) from implementation; implements a true compilation firewall; consider carefully the advantages (build time, insulation) and downsides (extra indirection level). Federico Ficarelli, Idiomatic C++ 30
  • 31. // myclass.h: class MyClass { private: struct MyClassPIMPL; MyClassPIMPL* pimpl_; // myclass.cpp: #include "myclass.h" // Forward // Handle public: Handle(); Handle(const Handle&); Handle& operator=(const Handle&); ~Handle(); // Other operations... }; // myclass.h: class MyClass { private: struct MyClassPIMPL; shared_ptr<MyClassPIMPL> pimpl_; public: // ... }; struct MyClass::MyClassPIMPL { int a, b; }; MyClass::MyClass() : pimpl_(new MyClassPIMPL()) { // do nothing } MyClass::MyClass(const MyClass& other) : pimpl_(new MyClassPIMPL(*(other.pimpl_))) { // do nothing } MyClass& MyClass::operator=(const MyClass &other) { delete pimpl_; *pimpl_ = *(other.pimpl_); return *this; } MyClass::~MyClass() { delete pimpl_; } Federico Ficarelli, Idiomatic C++ 31
  • 32. When implementing functionalities, the common belief is that OO prefers members. Function Placement: when implementing new functionalities, prefer non-member non-friend functions.   Improves encapsulation by minimizing dependencies: the function cannot depend nonpublic members (“Don’t give away your internals”); breaks apart monolithic classes to liberate separable functionalities, reducing coupling. Federico Ficarelli, Idiomatic C++ 32
  • 33. class NetworkBuffer { public: bool empty() { return this->device->get_packets_count() == 0; } /* ... */ }; class List { public: bool empty() { return this->length == 0; } /* ... */ }; class NetworkBuffer { public: size_t size() { return this->device->get_packets_count(); } /* ... */ }; class List { public: size_t size() { return this->length; } /* ... */ }; template<class T> bool empty( const T& s ) { return s.size() == 0; } Federico Ficarelli, Idiomatic C++ 33
  • 34. if (f needs to be virtual) make f a member function of C; else if (f is operator>> or operator<<) { make f a non-member function; if (f needs access to non-public members of C) make f a friend of C; } else if (f needs type conversions on its left-most argument) { make f a non-member function; if (f needs access to non-public members of C) make f a friend of C; } else if (f can be implemented via C's public interface) make f a non-member function; else make f a member function of C; Functions: the Meyer’s Algorithm [Effective C++] Federico Ficarelli, Idiomatic C++ 34
  • 35. 1. 2. 3. 4. 5. 6. Ensure resources are owned by objects. Use explicit RAII and smart pointers to expose ownership and enforce exception safety. Give one entity one cohesive responsibility. Keep your header files clean, don’t harm clients (nor yourself). PIMPL and DIP judiciously. Don’t optimize prematurely: correctness, simplicity and clarity come first. Don’t pessimize prematurely. Federico Ficarelli, Idiomatic C++ 35
  • 37. Design and implementation of the Big Four:  default construction,  copy construction;  copy assignment,  destruction. Pay attention:  compiler can generate them for you;  the language treats classes with value semantics by deafult. Federico Ficarelli, Idiomatic C++ 37
  • 38. Failing Constructors: “You should throw an exception from a constructor whenever you cannot properly initialize (construct) an object. There is no really satisfactory alternative to exiting a constructor by a throw”. [Stroustrup’s C++ FAQ]   Throwing from within a constructor is the most safe and widespread technique; the «init method» technique is unsafe and breaks RAII and all the idioms discussed in this chapter. Federico Ficarelli, Idiomatic C++ 38
  • 39. Warning: the constructor itself must be exception-safe (without relying on destructor). class T { public: T(std::size_t len = 0) : array( new int[len] ), buffer( new char[len]) {} // <-- ? // Destructor (omitted) private: int* array; char* buffer; }; class T { public: T(std::size_t len = 0) : array( new int[len] ), buffer( new char[len]) {} // <-- ? // Destructor (omitted) private: std::shared_array<int> array; std::shared_array<char> buffer; }; Federico Ficarelli, Idiomatic C++ 39
  • 40. Rule Of Three: if you need to explicitly declare either the destructor, copy constructor or copy assignment operator yourself, you probably need to explicitly declare all three of them. class dumb_string { public: dumb_string(std::size_t size = 0) : // conversion/default mSize(size), mArray(mSize ? new char[mSize]() : 0) {} dumb_string(const dumb_string& other) : // copy mSize(other.mSize), mArray(mSize ? new char[mSize]() : 0) { std::copy(other.mArray, other.mArray + mSize, mArray); } virtual ~dumb_string() { // destructor delete [] mArray; } private: std::size_t mSize; char* mArray; }; int main() { dumb_string a(10); dumb_string b(a); dumb_string c; c = a; // ? } Federico Ficarelli, Idiomatic C++ 40
  • 41. Disable Copying: whenever it makes sense, explicitly disable copy by construction and by assignment. This prevents the language from treating types with unwanted/erratic value semantics. #define DISALLOW_COPY_AND_ASSIGN(TypeName) TypeName(const TypeName&); void operator=(const TypeName&) // ... private: DISALLOW_COPY_AND_ASSIGN(T); }; template <class T> class NonCopyable { protected: NonCopyable () {} ~NonCopyable () {} // Protected non-virtual private: NonCopyable (const NonCopyable &); NonCopyable & operator = (const NonCopyable &); }; class CantCopy : private NonCopyable <CantCopy> {}; CRTP Mixin: enables Empty Base Optimization Federico Ficarelli, Idiomatic C++ 41
  • 42.   We need to implement the copy-assignment operator in order to have a correct value semantics; operator= is much more hard to implement in a robust way than the copy constructor:  must handle an already constructed object;  in case of failure, it must leave the object in the previous consistent state (rollback). The copy-assignment operator must be transactional. Federico Ficarelli, Idiomatic C++ 42
  • 43. dumb_string& operator=(const dumb_string& other) { if (this != &other) // <-{ // Tear down object’s state… delete [] mArray; // <-mArray = 0; // avoid double-deletion in case of RAII // ...and setup the new one... mSize = other.mSize; // <-mArray = mSize ? new int[mSize] : 0; std::copy(other.mArray, other.mArray + mSize, mArray); // <-} return *this; } Issues:  self assignment test: a symptom of non-robust implementation; usually very rare (performance waste);  non exception-safe. Federico Ficarelli, Idiomatic C++ 43
  • 44. dumb_string& operator=(const dumb_string& other) { if (this != &pOther) // <-{ // setup the new data ready before we teardown the old std::size_t newSize = other.mSize; int* newArray = newSize ? new int[newSize]() : 0; // <-std::copy(other.mArray, other.mArray + newSize, newArray); // replace the old data (all are nothrow) delete [] mArray; mSize = newSize; mArray = newArray; } return *this; } Issues:  code duplication. Federico Ficarelli, Idiomatic C++ 44
  • 45. friend void swap(dumb_string& first, dumb_string& second) throw() { std::swap(first.mSize, second.mSize); // throw() std::swap(first.mArray, second.mArray); // throw() } dumb_string& operator=(const dumb_string& other) { dumb_array temp(other); swap(*this, temp); // <-return *this; } dumb_string& operator=(dumb_string other) // <-{ swap(*this, other); // <-return *this; } Pass by Value: enables Copy Elision Optimization Rule-of-Three-and-a-half: whenever it makes sense, provide a no-fail swap. Enables strong exception-guarantee (especially the RVO version);  enables type to be used with a large number of idioms.  Federico Ficarelli, Idiomatic C++ 45
  • 46. Foundations Never Fail: everything that destructor, deallocation (e.g.: operator delete) and swap functions attempt shall succeed: never allow an error to be reported from within them. They are the foundation of transactional programming: without their resilience, no-fail rollback is impossible to implement. Federico Ficarelli, Idiomatic C++ 46
  • 47. When writing a class, consider:  Rule-of-three(and-a-half) to obtain correct and robust value semantics for complex types;  «None-of-three» for POD/aggregates (let the compiler generate them for you);  explicitly disable copy-construction and copy assignment. Federico Ficarelli, Idiomatic C++ 47
  • 49. Interface Principle: for a class T, all functions (including non-member) that both "mention" T and are "supplied with" T in the same namespace are logically part of T, because they form part of T's interface.  The language is explicitly designed to enforce the Interface Principle, ADL/Koenig Lookup was added for this reason. Federico Ficarelli, Idiomatic C++ 49
  • 50.  Only occurs if the normal lookup of an unqualified name fails to find a matching class member function. “The set of declarations [...] considered for resolution of the function name is the union of the declarations found by normal lookup with the declarations found by looking in the set of namespaces associated with the types of the function arguments”. [C++03, 3.4.2] // using namespace std; std::cout << "hello" << std::endl; Federico Ficarelli, Idiomatic C++ 50
  • 51. namespace type { class T { public: void f(); }; } namespace ops { T operator+( const T&, const T& ); } int main() { // using ops::operator+; type::T a, b; a.f(); type::T c = ops::operator+(a, b); } namespace ns { class T { public: void f(); }; T operator+( const T&, const T& ); } int main() { ns::T a, b; a.f(); ns::T c = a + b; } Interface Principle, corollary: keep a type and its non-member function interfaces in the same namespace. Federico Ficarelli, Idiomatic C++ 51
  • 52. #include <vector> namespace N { struct X {}; template <typename T> int* operator+( T, unsigned ) { /* do something */ } } int main() { std::vector<N::X> v(5); v[0]; // <-- v.begin() + 0 } Depending on std implementation, ADL may choose:  std::operator+  N::operator+ (pulled in the name search by vector<N::X>) Federico Ficarelli, Idiomatic C++ 52
  • 53. «Dual» Interface Principle: avoid putting non-member functions that are not part of the interface of a type T into the same namespace as T, and especially never put templated functions or operators into the same namespace as a userdefined type. Help prevent name-lookup accidents: protect types from unwanted ADL. Federico Ficarelli, Idiomatic C++ 53
  • 54. // f1.h namespace A { int f(double); } // g.h namespace B { using A::f; void g(); } // f2.h namespace A { int f(int); } Beware: B::g resolution (and semantics) depends on the headers inclusion order. Namespace Using Principle: // g.cpp B::g() { f(1); // <-- ? } avoid putting using namespace directives before any inclusion directive. Since the inclusion ordering is out of implementor’s control and depends on client’s implementation, never put using namespace directives inside header files. Federico Ficarelli, Idiomatic C++ 54
  • 55. Tools
  • 56.      Clang Static Analyzer Mozilla dehydra vera++ cppcheck Google cpplint Federico Ficarelli, Idiomatic C++ 56