c++ coding techniques - mysql community downloads · pdf file– i will demonstrate some...

48
1 Copyright 2005 MySQL AB The World’s Most Popular Open Source Database C++ Coding Techniques A collection of techniques for writing C++ code

Upload: lylien

Post on 13-Mar-2018

217 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

1Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

C++ Coding Techniques

A collection of techniques for writing C++ code

Page 2: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

2Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Outline for the session

• Building large systems– Why on earth do we bother?

• Programming Guidelines– Getting your code organized

• C++ Coding Idioms– Proven recepies

• C++ Gotcha's– Mistakes already made by others

Page 3: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

3Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Goals when building large systems

The system should promote:• Reusability• Extensibility• Flexibility

Page 4: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

4Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Reusability

• The system should consist of components that can be reused.

• Reusability is necessary to:– reduce the development time (long­term)– improve reliability of the system

Page 5: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

5Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Extensibility

Extensibility is necessary to:• Support extensions to the original system• Support addition of new features

Page 6: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

6Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Flexibility

• The system should not be rigid– A change in one component should not necessitate changes in other 

components

• Note:– Dependencies are not necessarily explicit– Problems not caught by compiler– Problems not caught by testing

Page 7: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

7Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Abstraction is everything!

• Encapsulation hides the internal implementation of a component

• Interfaces are used to provide methods for users to work with the component

• Inheritance is used to specialize an abstraction

Page 8: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

8Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Encapsulation

• The most important concept in OOP– No encapsuling... no object­orientation

• Hides the internals of a component• Provides an abstract interface for component users

– All operations are through the interface

• Allow the implementation to change– No requirement on component users to change their code

Page 9: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

9Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Encapsuling: example

class Writer {

public:

  ...

  void write(int i);

  void write(float f);

  void write(const char* c_str);

  ...

private:

  ...

};

Page 10: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

10Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Encapsuling: example of usage

class Point {

public:

  void write(Writer *writer) const {

    writer­>write(x);

    writer­>write(y);

  }

private:

  int x, y;

};

Page 11: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

11Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Encapsuling issues

• Encapsuling goals:– Maintain the object in a consistent state– Separate implementation and abstraction– Allow implementation to change

• Define methods for the abstraction• Do not define methods for the implementation

– I will demonstrate some examples in a few slides

Page 12: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

12Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Encapsuling issues, contd.

• Do not expose the internal state– Keep private parts to yourself!– Do not expose internals even through accessor functions– Make users rely on implementation– May allow users to (accidentally) change internal state:

• Impossible to maintain consistentency• Here be dragons!

Page 13: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

13Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

class Writer {public:  ...  void write(int i);  void write(float f);  void write(const char* c_str);  ...private:  WriteBuf m_buf;};

Encapsuling: example

Writer represents how data is written

WriteBuf represents where data is

written

Page 14: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

14Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Encapsuling: advantages of this code

• Interface completely hides internal implementation– WriteBuf and Writer can has completely different interfaces

• Implementation can be changed freely– Without affecting the interface– Hence without changing any code that uses the interface

Page 15: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

15Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Exposing internals: examples

• Expr::lhs() and Expr::rhs()– Method not defined for the abstraction– What if the expression is unary?

• Table::get_cache() and Table::clear_cache()

– Cache not part of the abstraction• Not a clear­cut case: depending on definition

– Object users will rely on its existance– What if you want to (re­)move it?

Page 16: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

16Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

A digression into mutable

• Expr represents an expression

• Hold a cache to avoid re­computations

• Cache represents a value cache

• Cache is inside Expr class

class Expr {  int compute () const {    if (cache.invalid())      cache.set(...);    return cache.val();  }

private:  ...  Cache cache;};

Page 17: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

17Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

A digression into mutability

• Consider an Expr class with a cache inside and consider the following code:

int eval(const Expr& expr) {  return expr.compute();}

$ g++ ­Wall ­ansi ­pedantic    mutable.cc   ­o mutablemutable.cc: In function 'int eval(const Expr&)':mutable.cc:33: error: no matching function for call to 'Expr::compute() const'mutable.cc:21: note: candidates are: int Expr::compute() <near match>

Page 18: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

18Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

A digression into mutability

• Instance e is const

• Cache inside the object?

• Fields inside const objects are immutable

• Code will not compile

• Use mutable

Valueeval(const Expr& e){  return e.compute();}

Page 19: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

19Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

A digression into mutable

• Cache or no cache is an implementation issue

• Implementation issues should not be visible in the interface

• Hence: use mutable

class Expr {  int compute () const {    if (cache.invalid())      cache.set(...);    return cache.val();  }

private:  ...  mutable Cache cache;};

Page 20: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

20Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Interfaces: what's it really about?

• Hiding the internals of a component• Policies for operating on an abstraction• Well­designed intefaces promote:

– Re­usability by abstracting the implementation– Flexibility by isolating independent parts from each other– Robustness by not allowing uncontrolled changes to the internals

Page 21: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

21Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Interface Design Guidelines

• Interfaces should be designed from the perspective of the caller– Interfaces are called many times, but implemented just a few

• Document before implementation– Write uses cases!– The more the better– No distraction from implementation issues

Page 22: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

22Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Use­case Driven Design

• Promotes complete interfaces– By writing use cases you put yourself in the role of the interface user

• Spot limitations in the interface• Encourages minimalistic interfaces

– Discourages creation of monolithic interfaces

Page 23: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

23Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Inheritance

• Specialization of an class• Implement an abstraction

– A special form of specialization

• Strategic extensibility– Possible to extend the system according to the policies set by the 

designer– Here policies are represented as classes with virtual functions

Page 24: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

24Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Inheritance

WriteBuf

FileWriteBuf

SocketWriteBuf

StringWriteBuf

WriterwriteTo

Page 25: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

25Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Inheritance: example

• A write buffer that data can be written to• Data is written as a block of bytes• If the buffer is in a “bad” state, no data will be written

class WriteBuf {public:  virtual size_t write(void *buf, size_t sz) = 0;  virtual bool is_good() const = 0;};

Page 26: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

26Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Inheritance: example

class FileWriteBuf : public WriteBuf {  FILE *m_file;      // is private by defaultpublic:  FileWriteBuf(char *name)  : m_file(fopen(name, “a+”)) { }

  size_t write(void *buf, size_t size) {    if (m_file)      return fwrite(buf, 1, size, m_file);    return 0;  }

  bool is_good() const { return m_file != 0; }};

Page 27: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

27Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

C++ Programming Techniques

A smörgåsbord of various C++ coding techniques and guidelines

Page 28: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

28Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Trust the compiler

• The compiler is your friend. Trust the compiler.– Trust... but verify– Check assembler output if necessary

• Compilers good at straightforward code– Use constants– Avoid dark corners of the standard

• Easy to understand means easy to optimize

Page 29: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

29Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Clever coding: an example

uchar foo_1(ulong a){  return !!(a << 11);}

uchar foo_2(ulong a) {  if (a & 0x1FFFFF)    return 1;  return 0;}

testl $2097151,8(%ebp)popl  %ebpsetne %alret

movl   8(%ebp), %eaxpopl   %ebpsall   $11, %eaxtestl  %eax, %eaxsetne  %almovzbl %al, %eaxret

Page 30: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

30Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

No gratuitous writes to memory

• Writing to memory cost– Bus speed vs. CPU speed

• Write cache­friendly code• Global variables cost• Local variables are cheap

• Branches cost• Write pipe­line friendly code• Recompute value?•

Page 31: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

31Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Gratuitous writes to memory: example

• Function comp() does not touch memory

• First version forces global variable to be written to memory before call

• Second version loads global variable into auto variable and writes back after computation

int func_g() {  g_var += comp(g_var);  g_var += comp(g_var);  g_var += comp(g_var);  return g_var;}

Memory accesses: 10 to 13

int func_l() {  int l_var = g_var;  l_var += comp(l_var);  l_var += comp(l_var);  l_var += comp(l_var);  return (g_var = l_var);}

Memory accesses: 5

Page 32: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

32Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Include file handling

• Always use include guards!• Never ever allow any circular includes!

– Include guards do not protect against circular dependencies– Check this on a regular basis– Symptom: weird error messages about incomplete or undefined 

structures and/or classes

• Organize module as:– Header file holding basic (non­class) definitions– Header file holding class definitions– Code file holding implementations

Page 33: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

33Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Module structure

• Header file– Include guard– Include what is used– Forward declare classes

• Source file– Module header file first– Include what is used– Standard header files last

– Forward declare classes

#ifndef FOO_H_INCLUDED#define FOO_H_INCLUDED

#include <cstdlib>

class Foo { ... };...#endif

#include “foo.h”#include <cstdlib>

Foo::Foo() { ... }

...

Page 34: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

34Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

RAII Idiom: Resource allocation is initialization

• Resources are aquired on construction• Resources are released on destruction

– Instance is destroyed automatically when leaving scope– No risk of forgetting to release resource

• Example:– Writing two items that should be written atomically.

bool packet(Writer& out, const char* str, int val){  Writer::Mutex mutex(out);  out.write(str);  out.write(val);  return out.is_good();}

Page 35: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

35Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

The Law of the Big Three

• If a class defines a copy constructor, a copy assignment operator, or a destructor, it probably needs to define all three.

• All three manipulate ownership of the resources used by an object

• If some operation is not allowed, make the function private– Declaration is sufficient, no definition necessary

Page 36: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

36Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Missing: Copy Constructor

class String {public:  String(const char *c_str)  : m_str(new char [strlen(c_str)]) { ... }

  ~String() { delete [] m_str; }

private:  const char *m_str;};

String make_string() {  String b(“Hello world”);  return b;}

Page 37: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

37Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Missing: assignment operator

class String {public:  ...  String(const String& that)  : m_str(new char [strlen(that.str)]) { ... }

private:  const char *m_str;};

String make_string() {  String a(“Hello ”);  String b;  b = a;  return b;}

Page 38: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

38Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Assignment operator: standard idiom

class String {public:  ...  String& operator=(const String& that) {    String copy(that);    swap(copy);    return *this;  }

  void swap(String& str) {    std::swap(m_str, str.m_str);  }  ...};

Page 39: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

39Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Assignment operator: idiom variations

// Slightly terser version of the previous oneString& String::operator(const String& that) {  String(that).swap(*this);  return *this;}

// More optimizer friendlyString& String::operator=(String that) {  swap(that);  return *this;}

Page 40: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

40Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Accessibility vs. visibility

class MyClass {private:  void store(int i) { ... }public:  void store(double f) { ... }};

void foo() {  MyClass c;  c.store(0);}

error: 'void Cell::store(int)' is private

error: within this context

char *

NULL

Page 41: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

41Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Virtual function handling

• Virtual functions should be private– Occationally protected, but never public

• Why?– Separate interface from implementation– Virtual functions are part of implementation– Implementation details should be hidden– Hence, virtual functions should be private

• Note:– Private functions can be overridden

Page 42: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

42Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Virtual Function Usage: example

class Base {public:  void tweak() {    do_tweak();  }private:  virtual void do_tweak() = 0;};

class Derived : public Base {private:  virtual void do_tweak() {    std::cout << “Hello World!” << std::endl;  }};

Page 43: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

43Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Gotcha's

Some pieces of code that does not work as you probably expect

Page 44: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

44Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

#1: Constructor Calling

• Calling virtual functions from constructors or destructors

• Object doesn't exist until after constructor completes

• Not an implementation issue!– Language design issue

class A {public:  A() { init(); }private:  virtual init();};

class B : public A {  ...private:  virtual init() { ... }};

Page 45: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

45Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

#2: Arrays of Objects

class A { ... };

class B : public A { ... int x; };

void foo(A a[]) { ... a[i] ... };

void bar() {

  B b[20];

  foo(b);    // ?!?!?

}

Page 46: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

46Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

#3: Initialization or... what?

class String {

public:

  String(const char *str) { ... }

};

class Concat : public Expr {

public:

  Concat(const String& a,

         const String& b) { ... }

  String value() const { ... }

};

Page 47: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

47Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

#3: Initialization or... what?

• If something looks like a declaration, it is• Parantheses are allowed around parameter names• str is declared as function accepting two String (instances) 

and returning a Concat (instance)

error: request for member 'value' in 'str', which is of non­class type 'Concat ()(String, String)'

int concat(char *a, char *b) {  Concat str(String(a), String(b));  return str.value();}

Page 48: C++ Coding Techniques - MySQL Community Downloads · PDF file– I will demonstrate some examples in a few slides. ... Inheritance: example class ... A smörgåsbord of various C++

48Copyright 2005 MySQL ABThe World’s Most Popular Open Source Database

Recommended reading

• Guru of the Week by Herb Sutterhttp://www.gotw.ca/

• Exceptional C++ Style by Herb Sutter• Modern C++ Programming by Andrei Alexandrescu• C++ Templates: The Complete Guide by David 

Vandevoorde and Nicolai M. Josuttis– Not for the faint­hearted