Vous êtes sur la page 1sur 21

void *pointers

 Loses all type information!

 Should be avoided when possible

 Make the C++ type system work for you,


don’t subvert it

 Interfaces to C libraries may require it


C Style Casts
 C style casts:
 do not communicate the intent of the cast
 can give the wrong answer
 Use relevant C++ casting operator
 communicates the intent of the cast
 gives the right answer
 Use constructor syntax for values
 int(floatFn()) instead of (int) floatFn()
const_cast<T>(expression)
 const_cast<T> changes the const or
volatile qualifier of its argument
 With T const *p
 use const_cast<T*>(p) instead of ((T *) p)
 Declare class members mutable if they
need to be updated from a const method
 Writing through a reference or pointer
stripped of its constness may cause
undefined behavior!
static_cast<T>(expression)
 Converts to type T, purely based on the
types present in expression.
 Use static_cast<T> when:
 you intend that the cast does not require any
run-time type information
 Cast enums to a numeric type (int, float, etc.)
 Cast from void pointer to T pointer
 Cast across the class hierarchy with multiple
inheritance; see
http://www.sjbrown.co.uk/2004/05/01/always-
use-static_cast/
dynamic_cast<T>(expressio
n)
 Requires RTTI to be enabled
 Only for pointers or references
 Returns 0 when object is not a T
 Resolves multiple inheritance properly
reinterpret_cast<T>
 The most evil of cast operators
 Subverts the type system completely
 Should only be needed when dealing
with C style APIs that don’t use void
pointers
Memory Allocation
 Any call to new or new[] should only
appear in a constructor
 Any call to delete or delete[] should only
appear in a destructor
 Encapsulate memory management in a
class
More on new and delete
 new/new[]
 does’t return 0 when memory is exhausted
 throws bad_alloc
 VC6 did it wrong; VS2005/gcc does it right
 No need to check for zero pointer returned
 delete/delete[]
 Deleting a zero pointer is harmless
 No need to check for zero pointer before calling
 Always match new[] with delete[] and
scalar new with scalar delete
Resource Acquisition
 Memory is just one kind of resource
 Others:
 critical section
 thread lock
 etc
 Treat identically to memory:
 acquire resource in c’tor
 release resource in d’tor
 RAII – Resource Acquisition Is Initialization
Exceptions
 Using RAII gives you exception safe
code for free
 Manual management of resources
requires try/catch blocks to ensure no
memory leaks when an exception is
thrown
std::auto_ptr<T>
 Takes ownership of whatever pointer
assigned to it
 ~auto_ptr() calls delete on the pointer
 release() returns the pointer and releases
ownership
 Calls scalar delete; doesn’t work for arrays
 Use for temporary buffers that are
destroyed when going out of scope or are
explicitly assigned to something else on
success
std::vector<T>
 Dynamically resizable array
 Great for fixed-size buffers you need to
create for C APIs when the size of the
buffer is determined at runtime.
 Use for temporary arrays of objects
 If used as an array of pointers, it doesn’t
call delete on each pointer
boost::shared_ptr<T>
 Reference counted pointer
 When reference count reaches zero,
delete is called on the underlying pointer
 Doesn’t guard against cycles
 Can be good when used carefully, but
can be bad when used excessively. It
becomes hard to identify the lifetime of
resources
 See boost docs for more
boost::ptr_vector<T>
 Boost container similar to
std::vector<T>, but calls delete on each
element when it is destroyed
 See boost docs for more
C style strings
 Don’t use them! Huge source of bugs.
 Use a string class:
 Qt’s QString
 C++ std::string
 C++ std::basic_string<TCHAR>
 wxWidgets wxString
 Pass string classes by const reference
 Return string classes by value or through
reference argument
 Use std::string::c_str() to talk to C APIs
Use of void
 Don’t use void argument lists:
 Use void foo() instead of void foo(void)
 Don’t use void pointers
 It completely subverts the type system,
leading to type errors
Callbacks
 C code can only call back through a
function pointer. A void pointer context
value is usually passed along to the
callback
 C++ code uses an interface pointer or
reference to communicate to its caller. No
need to supply a context value as the
interface pointer is associated with a class
that will hold all the context.
 Use interfaces instead of function pointers
for callbacks
#define
 Use enums to define groups of related
integer constants
 Use static const class members to define
integer or floating-point values. Declare
them in the .h, define them in the .cpp
 Use inline functions or methods for small
blocks of repeated code
 Use templates as a way to write type safe
macros that expand properly or generate a
compiler error
Static Polymorphism
 Static polymorphism exploits similarities
at compile time
 Dynamic polymorphism exploits
similarities at runtime
 Static polymorphism implemented with
templates
 Dynamic polymorphism implemented
with virtual methods on classes
#if, #else, #endif
 Used to express static variation in code
 When compiled one way, you get one
variation; when compiled the other way,
you get the other variation
 Better expressed through a template
class that expresses the two variations
as specifics of arguments to the
template
 Keeps syntactic checking on for both
variations all the time

Vous aimerez peut-être aussi