SlideShare a Scribd company logo
1 of 78
Download to read offline
C++ Idioms by Example, lesson 1
                           I
             Introducing some very basic C++ idioms, rules, guidelines and best practices
                           h
                           a

                                                              Olve Maudal
                                                             oma@pvv.org

                                                            November 2008




Disclaimer: most of the items I will discuss here are indeed idioms and conventions of the C++ language, something that most experts will
agree on. However some of the items are based on an ecolect – a programming style that is unique for a limited group of developers. There
are also a few items based on my idiolect, which is a programming style that I believe in. And you may argue that one or two things I
suggest here are just plain idiotic...

My intention is not to tell you how to do C++ programming. I hope to use this presentation as a catalyst for discussion, therefor I have also
included some controversial issues.

Ignite your flamethrower. Choose your battles!
Please criticise this program.

~/myprog/foo.hpp                                                     ~/myprog/foo.cpp
namespace bar {                                                      #include <iostream>
  class Foo {                                                        #include "foo.hpp"
     int _value;
     int my_magic(int a, int b);                                     using namespace std;
  public:
     Foo(int seed);                                                  namespace bar {
     int calc(int number = 7);                                         Foo::Foo(int seed) {
     int getValue() {                                                    _value = seed;
       return _value;                                                  }
     }
     void print(char* prefix);                                          int Foo::my_magic(int a, int b) {
  };                                                                      return a + b - 3 + 8 - 5;
}                                                                       }

                                                                        int Foo::calc(int number) {
                                                                          int result = my_magic(_value, number);
                                                                          _value += result;
~/myprog/main.cpp                                                         return result;
                                                                        }
#include "foo.hpp"
                                                                void Foo::print(char *prefix) {
int main() {                                                        cout << prefix << _value << "n";
  bar::Foo foo(2);                                              }
  char * prefix = "the answer=";                             }
  for(int i=0; i<4; i++) {
    foo.calc(i);

                                    Please criticise this program
  }
  foo.print(prefix);
  return 0;
}                             Spend 5-10 minutes to read through the code. Imagine that this is a piece of code that
                              you found in a larger codebase. Criticise everything you see,

                                    ... apart from the fact that it is a contrived, incorrect and stupid program that does not
                                    do anything useful, and is probably better written in Python as print “the
$ cd ~/myprog                       answer=42” (and do not spend time on the implmentation of my_magic)
$ g++ foo.cpp main.cpp && ./a.out
the answer=43
What do you see in this code?

        Happiness?
or trouble?
I see trouble.

It looks like the code has been written by someone
with little experience in C++, or even worse, by
someone who does not care...

Large amount of this kind of code will make your
codebase rot.

But, once you start to believe - it is time to defeat the
deteriorating agents
~/myprog/foo.hpp                    ~/myprog/foo.cpp
namespace bar {                     #include <iostream>
  class Foo {                       #include "foo.hpp"
     int _value;
     int my_magic(int a, int b);    using namespace std;
  public:
     Foo(int seed);                 namespace bar {
     int calc(int number = 7);        Foo::Foo(int seed) {
     int getValue() {                   _value = seed;
       return _value;                 }
     }
     void print(char* prefix);          int Foo::my_magic(int a, int b) {
  };                                      return a + b - 3 + 8 - 5;
}                                       }

                                        int Foo::calc(int number) {
                                          int result = my_magic(_value, number);
                                          _value += result;
~/myprog/main.cpp                         return result;
                                        }
#include "foo.hpp"
                                        void Foo::print(char *prefix) {
int main() {                              cout << prefix << _value << "n";
  bar::Foo foo(2);                      }
  char * prefix = "the answer=";    }
  for(int i=0; i<4; i++) {
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}




$ cd ~/myprog
$ g++ foo.cpp main.cpp && ./a.out
the answer=43
1. always compile with high warning level, and treat warnings as errors

~/myprog/foo.hpp                            ~/myprog/foo.cpp
namespace bar {                             #include <iostream>
  class Foo {                               #include "foo.hpp"
     int _value;
     int my_magic(int a, int b);            using namespace std;
  public:
     Foo(int seed);                         namespace bar {
     int calc(int number = 7);                Foo::Foo(int seed) {
     int getValue() {                           _value = seed;
       return _value;                         }
     }
     void print(char* prefix);                  int Foo::my_magic(int a, int b) {
  };                                              return a + b - 3 + 8 - 5;
}                                               }

                                                int Foo::calc(int number) {
                                                  int result = my_magic(_value, number);
                                                  _value += result;
~/myprog/main.cpp                                 return result;
                                                }
#include "foo.hpp"
                                                void Foo::print(char *prefix) {
int main() {                                      cout << prefix << _value << "n";
  bar::Foo foo(2);                              }
  char * prefix = "the answer=";            }
  for(int i=0; i<4; i++) {
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}




$ cd ~/myprog
$ g++ -Wall -Wextra -pedantic -Werror foo.cpp main.cpp && ./a.out
the answer=43
2. always use tools to support the building process

~/myprog/foo.hpp                                 ~/myprog/foo.cpp
namespace bar {                                  #include <iostream>
  class Foo {                                    #include "foo.hpp"
     int _value;
     int my_magic(int a, int b);                 using namespace std;
  public:
     Foo(int seed);
                       ~/myprog/Makefile
     int calc(int number = 7);
                                                 namespace bar {
                                                   Foo::Foo(int seed) {
     int getValue() {                                 _value = seed;
       return _value; CPPFLAGS=-Wall       -Wextra } -pedantic -Werror
     }                 LDFLAGS=
     void print(char* prefix);                       int Foo::my_magic(int a, int b) {
  };                                                   return a + b - 3 + 8 - 5;
}                      all: myprog                   }

                                                     int Foo::calc(int number) {
                  myprog: foo.o main.o   int result = my_magic(_value,               number);

~/myprog/main.cpp    $(CXX) -o $@ $(LDFLAGS) $+ result;
                                         _value +=
                                         return result;
                                                     }
#include "foo.hpp"
                     clean:                void Foo::print(char *prefix)           {
int main() {            rm -f foo.o main.o myprog prefix << _value <<
                                             cout <<                               "n";
  bar::Foo foo(2);                                   }
  char * prefix = "the answer=";                 }
  for(int i=0; i<4; i++) {
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}




$ cd ~/myprog
$ make
$ ./myprog
the answer=43
3. do not _prefix member variables, use postfix_ if you must

~/myprog/foo.hpp                            ~/myprog/foo.cpp
namespace bar {                             #include <iostream>
  class Foo {                               #include "foo.hpp"
     int _value;
     int my_magic(int a, int b);            using namespace std;
  public:
     Foo(int seed);                         namespace bar {
     int calc(int number = 7);                Foo::Foo(int seed) {
     int getValue() {                           _value = seed;
       return _value;                         }
     }
     void print(char* prefix);                  int Foo::my_magic(int a, int b) {
  };                                              return a + b - 3 + 8 - 5;
}                                               }

                                                int Foo::calc(int number) {
                                                  int result = my_magic(_value, number);
                                                  _value += result;
~/myprog/main.cpp                                 return result;
                                                }
#include "foo.hpp"
                                                void Foo::print(char *prefix) {
int main() {                                      cout << prefix << _value << "n";
  bar::Foo foo(2);                              }
  char * prefix = "the answer=";            }
  for(int i=0; i<4; i++) {
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}
3. do not _prefix member variables, use postfix_ if you must

~/myprog/foo.hpp                            ~/myprog/foo.cpp
namespace bar {                             #include <iostream>
  class Foo {                               #include "foo.hpp"
     int value_;
     int my_magic(int a, int b);            using namespace std;
  public:
     Foo(int seed);                         namespace bar {
     int calc(int number = 7);                Foo::Foo(int seed) {
     int getValue() {                           value_ = seed;
       return value_;                         }
     }
     void print(char* prefix);                  int Foo::my_magic(int a, int b) {
  };                                              return a + b - 3 + 8 - 5;
}                                               }

                                                int Foo::calc(int number) {
                                                  int result = my_magic(value_, number);
                                                  value_ += result;
~/myprog/main.cpp                                 return result;
                                                }
#include "foo.hpp"
                                                void Foo::print(char *prefix) {
int main() {                                      cout << prefix << value_ << "n";
  bar::Foo foo(2);                              }
  char * prefix = "the answer=";            }
  for(int i=0; i<4; i++) {
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}
4. public stuff should be declared first, then the private stuff

~/myprog/foo.hpp                               ~/myprog/foo.cpp
namespace bar {                                #include <iostream>
  class Foo {                                  #include "foo.hpp"
     int value_;
     int my_magic(int a, int b);               using namespace std;
  public:
     Foo(int seed);                            namespace bar {
     int calc(int number = 7);                   Foo::Foo(int seed) {
     int getValue() {                              value_ = seed;
       return value_;                            }
     }
     void print(char* prefix);                     int Foo::my_magic(int a, int b) {
  };                                                 return a + b - 3 + 8 - 5;
}                                                  }

                                                   int Foo::calc(int number) {
                                                     int result = my_magic(value_, number);
                                                     value_ += result;
~/myprog/main.cpp                                    return result;
                                                   }
#include "foo.hpp"
                                                   void Foo::print(char *prefix) {
int main() {                                         cout << prefix << value_ << "n";
  bar::Foo foo(2);                                 }
  char * prefix = "the answer=";               }
  for(int i=0; i<4; i++) {
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}
4. public stuff should be declared first, then the private stuff

~/myprog/foo.hpp                               ~/myprog/foo.cpp
namespace bar {                                #include <iostream>
  class Foo {                                  #include "foo.hpp"
  public:
     Foo(int seed);                            using namespace std;
     int calc(int number = 7);
     int getValue() {                          namespace bar {
       return value_;                            Foo::Foo(int seed) {
     }                                             value_ = seed;
     void print(char* prefix);                   }
  private:
     int value_;                                   int Foo::my_magic(int a, int b) {
     int my_magic(int a, int b);                     return a + b - 3 + 8 - 5;
  };                                               }
}
                                                   int Foo::calc(int number) {
                                                     int result = my_magic(value_, number);
                                                     value_ += result;
~/myprog/main.cpp                                    return result;
                                                   }
#include "foo.hpp"
                                                   void Foo::print(char *prefix) {
int main() {                                         cout << prefix << value_ << "n";
  bar::Foo foo(2);                                 }
  char * prefix = "the answer=";               }
  for(int i=0; i<4; i++) {
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}
5. single argument constructors should usually be explicit

~/myprog/foo.hpp                            ~/myprog/foo.cpp
namespace bar {                             #include <iostream>
  class Foo {                               #include "foo.hpp"
  public:
     Foo(int seed);                         using namespace std;
     int calc(int number = 7);
     int getValue() {                       namespace bar {
       return value_;                         Foo::Foo(int seed) {
     }                                          value_ = seed;
     void print(char* prefix);                }
  private:
     int value_;                                int Foo::my_magic(int a, int b) {
     int my_magic(int a, int b);                  return a + b - 3 + 8 - 5;
  };                                            }
}
                                                int Foo::calc(int number) {
                                                  int result = my_magic(value_, number);
                                                  value_ += result;
~/myprog/main.cpp                                 return result;
                                                }
#include "foo.hpp"
                                                void Foo::print(char *prefix) {
int main() {                                      cout << prefix << value_ << "n";
  bar::Foo foo(2);                              }
  char * prefix = "the answer=";            }
  for(int i=0; i<4; i++) {
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}
5. single argument constructors should usually be explicit

~/myprog/foo.hpp                            ~/myprog/foo.cpp
namespace bar {                             #include <iostream>
  class Foo {                               #include "foo.hpp"
  public:
     explicit Foo(int seed);                using namespace std;
     int calc(int number = 7);
     int getValue() {                       namespace bar {
       return value_;                         Foo::Foo(int seed) {
     }                                          value_ = seed;
     void print(char* prefix);                }
  private:
     int value_;                                int Foo::my_magic(int a, int b) {
     int my_magic(int a, int b);                  return a + b - 3 + 8 - 5;
  };                                            }
}
                                                int Foo::calc(int number) {
                                                  int result = my_magic(value_, number);
                                                  value_ += result;
~/myprog/main.cpp                                 return result;
                                                }
#include "foo.hpp"
                                                void Foo::print(char *prefix) {
int main() {                                      cout << prefix << value_ << "n";
  bar::Foo foo(2);                              }
  char * prefix = "the answer=";            }
  for(int i=0; i<4; i++) {
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}
6. initialize the state of the object properly

~/myprog/foo.hpp                                 ~/myprog/foo.cpp
namespace bar {                                  #include <iostream>
  class Foo {                                    #include "foo.hpp"
  public:
     explicit Foo(int seed);                     using namespace std;
     int calc(int number = 7);
     int getValue() {                            namespace bar {
       return value_;                              Foo::Foo(int seed) {
     }                                               value_ = seed;
     void print(char* prefix);                     }
  private:
     int value_;                                     int Foo::my_magic(int a, int b) {
     int my_magic(int a, int b);                       return a + b - 3 + 8 - 5;
  };                                                 }
}
                                                     int Foo::calc(int number) {
                                                       int result = my_magic(value_, number);
                                                       value_ += result;
~/myprog/main.cpp                                      return result;
                                                     }
#include "foo.hpp"
                                                     void Foo::print(char *prefix) {
int main() {                                           cout << prefix << value_ << "n";
  bar::Foo foo(2);                                   }
  char * prefix = "the answer=";                 }
  for(int i=0; i<4; i++) {
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}
6. initialize the state of the object properly

~/myprog/foo.hpp                                 ~/myprog/foo.cpp
namespace bar {                                  #include <iostream>
  class Foo {                                    #include "foo.hpp"
  public:
     explicit Foo(int seed);                     using namespace std;
     int calc(int number = 7);
     int getValue() {                            namespace bar {
       return value_;                              Foo::Foo(int seed) : value_(seed) {
     }                                             }
     void print(char* prefix);
  private:                                           int Foo::my_magic(int a, int b) {
     int value_;                                       return a + b - 3 + 8 - 5;
     int my_magic(int a, int b);                     }
  };
}                                                    int Foo::calc(int number) {
                                                       int result = my_magic(value_, number);
                                                       value_ += result;
                                                       return result;
~/myprog/main.cpp                                    }
#include "foo.hpp"                                   void Foo::print(char *prefix) {
                                                       cout << prefix << value_ << "n";
int main() {                                         }
  bar::Foo foo(2);                               }
  char * prefix = "the answer=";
  for(int i=0; i<4; i++) {
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}
7. use a consistent naming convention, camelCase or under_score

~/myprog/foo.hpp                         ~/myprog/foo.cpp
namespace bar {                          #include <iostream>
  class Foo {                            #include "foo.hpp"
  public:
     explicit Foo(int seed);             using namespace std;
     int calc(int number = 7);
     int getValue() {                    namespace bar {
       return value_;                      Foo::Foo(int seed) : value_(seed) {
     }                                     }
     void print(char* prefix);
  private:                                   int Foo::my_magic(int a, int b) {
     int value_;                               return a + b - 3 + 8 - 5;
     int my_magic(int a, int b);             }
  };
}                                            int Foo::calc(int number) {
                                               int result = my_magic(value_, number);
                                               value_ += result;
                                               return result;
~/myprog/main.cpp                            }
#include "foo.hpp"                           void Foo::print(char *prefix) {
                                               cout << prefix << value_ << "n";
int main() {                                 }
  bar::Foo foo(2);                       }
  char * prefix = "the answer=";
  for(int i=0; i<4; i++) {
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}
7. use a consistent naming convention, camelCase or under_score

~/myprog/foo.hpp                         ~/myprog/foo.cpp
namespace bar {                          #include <iostream>
  class Foo {                            #include "foo.hpp"
  public:
     explicit Foo(int seed);             using namespace std;
     int calc(int number = 7);
     int getValue() {                    namespace bar {
       return value_;                      Foo::Foo(int seed) : value_(seed) {
     }                                     }
     void print(char* prefix);
  private:                                   int Foo::myMagic(int a, int b) {
     int value_;                               return a + b - 3 + 8 - 5;
     int myMagic(int a, int b);              }
  };
}                                            int Foo::calc(int number) {
                                               int result = myMagic(value_, number);
                                               value_ += result;
                                               return result;
~/myprog/main.cpp                            }
#include "foo.hpp"                           void Foo::print(char *prefix) {
                                               cout << prefix << value_ << "n";
int main() {                                 }
  bar::Foo foo(2);                       }
  char * prefix = "the answer=";
  for(int i=0; i<4; i++) {
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}
8. do not prefix queries and modifiers with get/set

~/myprog/foo.hpp                             ~/myprog/foo.cpp
namespace bar {                              #include <iostream>
  class Foo {                                #include "foo.hpp"
  public:
     explicit Foo(int seed);                 using namespace std;
     int calc(int number = 7);
     int getValue() {                        namespace bar {
       return value_;                          Foo::Foo(int seed) : value_(seed) {
     }                                         }
     void print(char* prefix);
  private:                                       int Foo::myMagic(int a, int b) {
     int value_;                                   return a + b - 3 + 8 - 5;
     int myMagic(int a, int b);                  }
  };
}                                                int Foo::calc(int number) {
                                                   int result = myMagic(value_, number);
                                                   value_ += result;
                                                   return result;
~/myprog/main.cpp                                }
#include "foo.hpp"                               void Foo::print(char *prefix) {
                                                   cout << prefix << value_ << "n";
int main() {                                     }
  bar::Foo foo(2);                           }
  char * prefix = "the answer=";
  for(int i=0; i<4; i++) {
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}
8. do not prefix queries and modifiers with get/set

~/myprog/foo.hpp                             ~/myprog/foo.cpp
namespace bar {                              #include <iostream>
  class Foo {                                #include "foo.hpp"
  public:
     explicit Foo(int seed);                 using namespace std;
     int calc(int number = 7);
     int value() {                           namespace bar {
       return value_;                          Foo::Foo(int seed) : value_(seed) {
     }                                         }
     void print(char* prefix);
  private:                                       int Foo::myMagic(int a, int b) {
     int value_;                                   return a + b - 3 + 8 - 5;
     int myMagic(int a, int b);                  }
  };
}                                                int Foo::calc(int number) {
                                                   int result = myMagic(value_, number);
                                                   value_ += result;
                                                   return result;
~/myprog/main.cpp                                }
#include "foo.hpp"                               void Foo::print(char *prefix) {
                                                   cout << prefix << value_ << "n";
int main() {                                     }
  bar::Foo foo(2);                           }
  char * prefix = "the answer=";
  for(int i=0; i<4; i++) {
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}
9. do not import namespaces

~/myprog/foo.hpp                   ~/myprog/foo.cpp
namespace bar {                    #include <iostream>
  class Foo {                      #include "foo.hpp"
  public:
     explicit Foo(int seed);       using namespace std;
     int calc(int number = 7);
     int value() {                 namespace bar {
       return value_;                Foo::Foo(int seed) : value_(seed) {
     }                               }
     void print(char* prefix);
  private:                             int Foo::myMagic(int a, int b) {
     int value_;                         return a + b - 3 + 8 - 5;
     int myMagic(int a, int b);        }
  };
}                                      int Foo::calc(int number) {
                                         int result = myMagic(value_, number);
                                         value_ += result;
                                         return result;
~/myprog/main.cpp                      }
#include "foo.hpp"                     void Foo::print(char *prefix) {
                                         cout << prefix << value_ << "n";
int main() {                           }
  bar::Foo foo(2);                 }
  char * prefix = "the answer=";
  for(int i=0; i<4; i++) {
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}
9. do not import namespaces

~/myprog/foo.hpp                   ~/myprog/foo.cpp
namespace bar {                    #include <iostream>
  class Foo {                      #include "foo.hpp"
  public:
     explicit Foo(int seed);       namespace bar {
     int calc(int number = 7);       Foo::Foo(int seed) : value_(seed) {
     int value() {                   }
       return value_;
     }                                 int Foo::myMagic(int a, int b) {
     void print(char* prefix);           return a + b - 3 + 8 - 5;
  private:                             }
     int value_;
     int myMagic(int a, int b);        int Foo::calc(int number) {
  };                                     int result = myMagic(value_, number);
}                                        value_ += result;
                                         return result;
                                       }

~/myprog/main.cpp                      void Foo::print(char *prefix) {
                                         std::cout << prefix << value_ << "n";
#include "foo.hpp"                     }
                                   }
int main() {
  bar::Foo foo(2);
  char * prefix = "the answer=";
  for(int i=0; i<4; i++) {
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}
10. query functions should be declared const

~/myprog/foo.hpp                           ~/myprog/foo.cpp
namespace bar {                            #include <iostream>
  class Foo {                              #include "foo.hpp"
  public:
     explicit Foo(int seed);               namespace bar {
     int calc(int number = 7);               Foo::Foo(int seed) : value_(seed) {
     int value() {                           }
       return value_;
     }                                         int Foo::myMagic(int a, int b) {
     void print(char* prefix);                   return a + b - 3 + 8 - 5;
  private:                                     }
     int value_;
     int myMagic(int a, int b);                int Foo::calc(int number) {
  };                                             int result = myMagic(value_, number);
}                                                value_ += result;
                                                 return result;
                                               }

~/myprog/main.cpp                              void Foo::print(char *prefix) {
                                                 std::cout << prefix << value_ << "n";
#include "foo.hpp"                             }
                                           }
int main() {
  bar::Foo foo(2);
  char * prefix = "the answer=";
  for(int i=0; i<4; i++) {
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}
10. query functions should be declared const

~/myprog/foo.hpp                           ~/myprog/foo.cpp
namespace bar {                            #include <iostream>
  class Foo {                              #include "foo.hpp"
  public:
     explicit Foo(int seed);               namespace bar {
     int calc(int number = 7);               Foo::Foo(int seed) : value_(seed) {
     int value() const {                     }
       return value_;
     }                                         int Foo::myMagic(int a, int b) {
     void print(char* prefix) const;             return a + b - 3 + 8 - 5;
  private:                                     }
     int value_;
     int myMagic(int a, int b);                int Foo::calc(int number) {
  };                                             int result = myMagic(value_, number);
}                                                value_ += result;
                                                 return result;
                                               }

~/myprog/main.cpp                              void Foo::print(char *prefix) const {
                                                 std::cout << prefix << value_ << "n";
#include "foo.hpp"                             }
                                           }
int main() {
  bar::Foo foo(2);
  char * prefix = "the answer=";
  for(int i=0; i<4; i++) {
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}
11. non-const functions are modifiers

~/myprog/foo.hpp                        ~/myprog/foo.cpp
namespace bar {                         #include <iostream>
  class Foo {                           #include "foo.hpp"
  public:
     explicit Foo(int seed);            namespace bar {
     int calc(int number = 7);            Foo::Foo(int seed) : value_(seed) {
     int value() const {                  }


                                                                               ?
       return value_;
     }                                      int Foo::myMagic(int a, int b) {
     void print(char* prefix) const;          return a + b - 3 + 8 - 5;
  private:                                  }
     int value_;
     int myMagic(int a, int b);             int Foo::calc(int number) {
  };                                          int result = myMagic(value_, number);
}                                             value_ += result;
                                              return result;
                                            }

~/myprog/main.cpp                           void Foo::print(char *prefix) const {
                                              std::cout << prefix << value_ << "n";
#include "foo.hpp"                          }
                                        }
int main() {
  bar::Foo foo(2);
  char * prefix = "the answer=";
  for(int i=0; i<4; i++) {
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}
12. prefer free-standing functions

~/myprog/foo.hpp                       ~/myprog/foo.cpp
namespace bar {                        #include <iostream>
  class Foo {                          #include "foo.hpp"
  public:
     explicit Foo(int seed);           namespace bar {
     int calc(int number = 7);           Foo::Foo(int seed) : value_(seed) {
     int value() const {                 }
       return value_;
     }                                     int Foo::myMagic(int a, int b) {
     void print(char* prefix) const;         return a + b - 3 + 8 - 5;
  private:                                 }
     int value_;
     int myMagic(int a, int b);            int Foo::calc(int number) {
  };                                         int result = myMagic(value_, number);
}                                            value_ += result;
                                             return result;
                                           }

~/myprog/main.cpp                          void Foo::print(char *prefix) const {
                                             std::cout << prefix << value_ << "n";
#include "foo.hpp"                         }
                                       }
int main() {
  bar::Foo foo(2);
  char * prefix = "the answer=";
  for(int i=0; i<4; i++) {
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}
12. prefer free-standing functions

~/myprog/foo.hpp                       ~/myprog/foo.cpp
namespace bar {                        #include <iostream>
  class Foo {                          #include "foo.hpp"
  public:
     explicit Foo(int seed);           namespace bar {
     int calc(int number = 7);           Foo::Foo(int seed) : value_(seed) {
     int value() const {                 }
       return value_;
     }                                     int Foo::myMagic(int a, int b) {
     void print(char* prefix) const;         return a + b - 3 + 8 - 5;
  private:                                 }
     int value_;
     int myMagic(int a, int b);            int Foo::calc(int number) {
  };                                         int result = myMagic(value_, number);
}                                            value_ += result;
                                             return result;
                                           }

~/myprog/main.cpp                          void Foo::print(char *prefix) const {
                                             std::cout << prefix << value_ << "n";
#include "foo.hpp"                         }
                                       }
int main() {
  bar::Foo foo(2);
  char * prefix = "the answer=";
  for(int i=0; i<4; i++) {
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}
12. prefer free-standing functions

~/myprog/foo.hpp                       ~/myprog/foo.cpp
namespace bar {                        #include <iostream>
  class Foo {                          #include "foo.hpp"
  public:
     explicit Foo(int seed);           namespace bar {
     int calc(int number = 7);           Foo::Foo(int seed) : value_(seed) {
     int value() const {                 }
       return value_;
     }                                     int myMagic(int a, int b) {
     void print(char* prefix) const;         return a + b - 3 + 8 - 5;
  private:                                 }
     int value_;
  };                                       int Foo::calc(int number) {
}                                            int result = myMagic(value_, number);
                                             value_ += result;
                                             return result;
                                           }

~/myprog/main.cpp                          void Foo::print(char *prefix) const {
                                             std::cout << prefix << value_ << "n";
#include "foo.hpp"                         }
                                       }
int main() {
  bar::Foo foo(2);
  char * prefix = "the answer=";
  for(int i=0; i<4; i++) {
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}
13. use anonymous namespaces for private free-standing functions

~/myprog/foo.hpp                         ~/myprog/foo.cpp
namespace bar {                          #include <iostream>
  class Foo {                            #include "foo.hpp"
  public:
     explicit Foo(int seed);             namespace bar {
     int calc(int number = 7);             Foo::Foo(int seed) : value_(seed) {
     int value() const {                   }
       return value_;
     }                                       int myMagic(int a, int b) {
     void print(char* prefix) const;           return a + b - 3 + 8 - 5;
  private:                                   }
     int value_;
  };                                         int Foo::calc(int number) {
}                                              int result = myMagic(value_, number);
                                               value_ += result;
                                               return result;
                                             }

~/myprog/main.cpp                            void Foo::print(char *prefix) const {
                                               std::cout << prefix << value_ << "n";
#include "foo.hpp"                           }
                                         }
int main() {
  bar::Foo foo(2);
  char * prefix = "the answer=";
  for(int i=0; i<4; i++) {
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}
13. use anonymous namespaces for private free-standing functions

~/myprog/foo.hpp                         ~/myprog/foo.cpp
namespace bar {                          #include <iostream>
  class Foo {                            #include "foo.hpp"
  public:
     explicit Foo(int seed);             namespace {
     int calc(int number = 7);             int myMagic(int a, int b) {
     int value() const {                     return a + b - 3 + 8 - 5;
       return value_;                      }
     }                                   }
     void print(char* prefix) const;
  private:                               namespace bar {
     int value_;                           Foo::Foo(int seed) : value_(seed) {
  };                                       }
}
                                             int Foo::calc(int number) {
                                               int result = myMagic(value_, number);
                                               value_ += result;
                                               return result;
~/myprog/main.cpp                            }
#include "foo.hpp"                           void Foo::print(char *prefix) const {
                                               std::cout << prefix << value_ << "n";
int main() {                                 }
  bar::Foo foo(2);                       }
  char * prefix = "the answer=";
  for(int i=0; i<4; i++) {
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}
14. do not inline stuff in the class definition

~/myprog/foo.hpp                                  ~/myprog/foo.cpp
namespace bar {                                   #include <iostream>
  class Foo {                                     #include "foo.hpp"
  public:
     explicit Foo(int seed);                      namespace {
     int calc(int number = 7);                      int myMagic(int a, int b) {
     int value() const {                              return a + b - 3 + 8 - 5;
       return value_;                               }
     }                                            }
     void print(char* prefix) const;
  private:                                        namespace bar {
     int value_;                                    Foo::Foo(int seed) : value_(seed) {
  };                                                }
}
                                                      int Foo::calc(int number) {
                                                        int result = myMagic(value_, number);
                                                        value_ += result;
                                                        return result;
~/myprog/main.cpp                                     }
#include "foo.hpp"                                    void Foo::print(char *prefix) const {
                                                        std::cout << prefix << value_ << "n";
int main() {                                          }
  bar::Foo foo(2);                                }
  char * prefix = "the answer=";
  for(int i=0; i<4; i++) {
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}
14. do not inline stuff in the class definition

~/myprog/foo.hpp                                  ~/myprog/foo.cpp
namespace bar {                                   #include <iostream>
  class Foo {                                     #include "foo.hpp"
  public:
     explicit Foo(int seed);                      namespace {
     int calc(int number = 7);                      int myMagic(int a, int b) {
     int value() const;                               return a + b - 3 + 8 - 5;
     void print(char* prefix) const;                }
  private:                                        }
     int value_;
  };                                              namespace bar {
                                                    Foo::Foo(int seed) : value_(seed) {
    inline int Foo::value() const {                 }
      return value_;
    }                                                 int Foo::calc(int number) {
}                                                       int result = myMagic(value_, number);
                                                        value_ += result;
                                                        return result;
~/myprog/main.cpp                                     }
#include "foo.hpp"                                    void Foo::print(char *prefix) const {
                                                        std::cout << prefix << value_ << "n";
int main() {                                          }
  bar::Foo foo(2);                                }
  char * prefix = "the answer=";
  for(int i=0; i<4; i++) {
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}
15. by default keep your stuff in the implementation file

~/myprog/foo.hpp                             ~/myprog/foo.cpp
namespace bar {                              #include <iostream>
  class Foo {                                #include "foo.hpp"
  public:
     explicit Foo(int seed);                 namespace {
     int calc(int number = 7);                 int myMagic(int a, int b) {
     int value() const;                          return a + b - 3 + 8 - 5;
     void print(char* prefix) const;           }
  private:                                   }
     int value_;
  };                                         namespace bar {
                                               Foo::Foo(int seed) : value_(seed) {
    inline int Foo::value() const {            }
      return value_;
    }                                            int Foo::calc(int number) {
}                                                  int result = myMagic(value_, number);
                                                   value_ += result;
                                                   return result;
~/myprog/main.cpp                                }
#include "foo.hpp"                               void Foo::print(char *prefix) const {
                                                   std::cout << prefix << value_ << "n";
int main() {                                     }
  bar::Foo foo(2);                           }
  char * prefix = "the answer=";
  for(int i=0; i<4; i++) {
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}
15. by default keep your stuff in the implementation file

~/myprog/foo.hpp                             ~/myprog/foo.cpp
namespace bar {                              #include <iostream>
  class Foo {                                #include "foo.hpp"
  public:
     explicit Foo(int seed);                 namespace {
     int calc(int number = 7);                 int myMagic(int a, int b) {
     int value() const;                          return a + b - 3 + 8 - 5;
     void print(char* prefix) const;           }
  private:                                   }
     int value_;
  };                                         namespace bar {
}                                              Foo::Foo(int seed) : value_(seed) {
                                               }

                                                 int Foo::calc(int number) {
                                                   int result = myMagic(value_, number);
                                                   value_ += result;
                                                   return result;
~/myprog/main.cpp                                }
#include "foo.hpp"                               int Foo::value() const {
                                                   return value_;
int main() {                                     }
  bar::Foo foo(2);
  char * prefix = "the answer=";                 void Foo::print(char *prefix) const {
  for(int i=0; i<4; i++) {                         std::cout << prefix << value_ << "n";
    foo.calc(i);                                 }
  }                                          }
  foo.print(prefix);
  return 0;
}
16. avoid member functions that both modifies and queries

~/myprog/foo.hpp                          ~/myprog/foo.cpp
namespace bar {                           #include <iostream>
  class Foo {                             #include "foo.hpp"
  public:
     explicit Foo(int seed);              namespace {
     int calc(int number = 7);              int myMagic(int a, int b) {
     int value() const;                       return a + b - 3 + 8 - 5;
     void print(char* prefix) const;        }
  private:                                }
     int value_;
  };                                      namespace bar {
}                                           Foo::Foo(int seed) : value_(seed) {
                                            }

                                              int Foo::calc(int number) {
                                                int result = myMagic(value_, number);
                                                value_ += result;
                                                return result;
~/myprog/main.cpp                             }
#include "foo.hpp"                            int Foo::value() const {
                                                return value_;
int main() {                                  }
  bar::Foo foo(2);
  char * prefix = "the answer=";              void Foo::print(char *prefix) const {
  for(int i=0; i<4; i++) {                      std::cout << prefix << value_ << "n";
    foo.calc(i);                              }
  }                                       }
  foo.print(prefix);
  return 0;
}
16. avoid member functions that both modifies and queries

~/myprog/foo.hpp                          ~/myprog/foo.cpp
namespace bar {                           #include <iostream>
  class Foo {                             #include "foo.hpp"
  public:
     explicit Foo(int seed);              namespace {
     void calc(int number = 7);             int myMagic(int a, int b) {
     int value() const;                       return a + b - 3 + 8 - 5;
     void print(char* prefix) const;        }
  private:                                }
     int value_;
  };                                      namespace bar {
}                                           Foo::Foo(int seed) : value_(seed) {
                                            }

                                              void Foo::calc(int number) {
                                                value_ += myMagic(value_, number);
                                              }

~/myprog/main.cpp                             int Foo::value() const {
                                                return value_;
#include "foo.hpp"                            }
int main() {                                  void Foo::print(char *prefix) const {
  bar::Foo foo(2);                              std::cout << prefix << value_ << "n";
  char * prefix = "the answer=";              }
  for(int i=0; i<4; i++) {                }
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}
17. default arguments are depreciated, use delegation if you must

~/myprog/foo.hpp                           ~/myprog/foo.cpp
namespace bar {                            #include <iostream>
  class Foo {                              #include "foo.hpp"
  public:
     explicit Foo(int seed);               namespace {
     void calc(int number = 7);              int myMagic(int a, int b) {
     int value() const;                        return a + b - 3 + 8 - 5;
     void print(char* prefix) const;         }
  private:                                 }
     int value_;
  };                                       namespace bar {
}                                            Foo::Foo(int seed) : value_(seed) {
                                             }

                                               void Foo::calc(int number) {
                                                 value_ += myMagic(value_, number);
                                               }

~/myprog/main.cpp                              int Foo::value() const {
                                                 return value_;
#include "foo.hpp"                             }
int main() {                                   void Foo::print(char *prefix) const {
  bar::Foo foo(2);                               std::cout << prefix << value_ << "n";
  char * prefix = "the answer=";               }
  for(int i=0; i<4; i++) {                 }
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}
17. default arguments are depreciated, use delegation if you must

~/myprog/foo.hpp                           ~/myprog/foo.cpp
namespace bar {                            #include <iostream>
  class Foo {                              #include "foo.hpp"
  public:
     explicit Foo(int seed);               namespace {
     void calc(int number);                  int myMagic(int a, int b) {
     int value() const;                        return a + b - 3 + 8 - 5;
     void print(char* prefix) const;         }
  private:                                 }
     int value_;
  };                                       namespace bar {
}                                            Foo::Foo(int seed) : value_(seed) {
                                             }

                                               void Foo::calc(int number) {
                                                 value_ += myMagic(value_, number);
                                               }

~/myprog/main.cpp                              int Foo::value() const {
                                                 return value_;
#include "foo.hpp"                             }
int main() {                                   void Foo::print(char *prefix) const {
  bar::Foo foo(2);                               std::cout << prefix << value_ << "n";
  char * prefix = "the answer=";               }
  for(int i=0; i<4; i++) {                 }
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}
18. the K&R vs BS war is over, use an extra space around & and *

~/myprog/foo.hpp                          ~/myprog/foo.cpp
namespace bar {                           #include <iostream>
  class Foo {                             #include "foo.hpp"
  public:
     explicit Foo(int seed);              namespace {
     void calc(int number);                 int myMagic(int a, int b) {
     int value() const;                       return a + b - 3 + 8 - 5;
     void print(char* prefix) const;        }
  private:                                }
     int value_;
  };                                      namespace bar {
}                                           Foo::Foo(int seed) : value_(seed) {
                                            }

                                              void Foo::calc(int number) {
                                                value_ += myMagic(value_, number);
                                              }

~/myprog/main.cpp                             int Foo::value() const {
                                                return value_;
#include "foo.hpp"                            }
int main() {                                  void Foo::print(char *prefix) const {
  bar::Foo foo(2);                              std::cout << prefix << value_ << "n";
  char * prefix = "the answer=";              }
  for(int i=0; i<4; i++) {                }
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}
18. the K&R vs BS war is over, use an extra space around & and *

~/myprog/foo.hpp                          ~/myprog/foo.cpp
namespace bar {                           #include <iostream>
  class Foo {                             #include "foo.hpp"
  public:
     explicit Foo(int seed);              namespace {
     void calc(int number);                 int myMagic(int a, int b) {
     int value() const;                       return a + b - 3 + 8 - 5;
     void print(char * prefix) const;       }
  private:                                }
     int value_;
  };                                      namespace bar {
}                                           Foo::Foo(int seed) : value_(seed) {
                                            }

                                              void Foo::calc(int number) {
                                                value_ += myMagic(value_, number);
                                              }

~/myprog/main.cpp                             int Foo::value() const {
                                                return value_;
#include "foo.hpp"                            }
int main() {                                  void Foo::print(char * prefix) const {
  bar::Foo foo(2);                              std::cout << prefix << value_ << "n";
  char * prefix = "the answer=";              }
  for(int i=0; i<4; i++) {                }
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}
19. by not specifying const you say that something will change

~/myprog/foo.hpp                           ~/myprog/foo.cpp
namespace bar {                            #include <iostream>
  class Foo {                              #include "foo.hpp"
  public:
     explicit Foo(int seed);               namespace {
     void calc(int number);                  int myMagic(int a, int b) {
     int value() const;                        return a + b - 3 + 8 - 5;
     void print(char * prefix) const;        }
  private:                                 }
     int value_;
  };                                       namespace bar {
}                                            Foo::Foo(int seed) : value_(seed) {
                                             }

                                               void Foo::calc(int number) {
                                                 value_ += myMagic(value_, number);
                                               }

~/myprog/main.cpp                              int Foo::value() const {
                                                 return value_;
#include "foo.hpp"                             }
int main() {                                   void Foo::print(char * prefix) const {
  bar::Foo foo(2);                               std::cout << prefix << value_ << "n";
  char * prefix = "the answer=";               }
  for(int i=0; i<4; i++) {                 }
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}
19. by not specifying const you say that something will change

~/myprog/foo.hpp                              ~/myprog/foo.cpp
namespace bar {                               #include <iostream>
  class Foo {                                 #include "foo.hpp"
  public:
     explicit Foo(int seed);                  namespace {
     void calc(int number);                     int myMagic(int a, int b) {
     int value() const;                           return a + b - 3 + 8 - 5;
     void print(const char * prefix) const;     }
  private:                                    }
     int value_;
  };                                          namespace bar {
}                                               Foo::Foo(int seed) : value_(seed) {
                                                }

                                                  void Foo::calc(int number) {
                                                    value_ += myMagic(value_, number);
                                                  }

~/myprog/main.cpp                                 int Foo::value() const {
                                                    return value_;
#include "foo.hpp"                                }
int main() {                                      void Foo::print(const char * prefix) const {
  bar::Foo foo(2);                                  std::cout << prefix << value_ << "n";
  const char * prefix = "the answer=";            }
  for(int i=0; i<4; i++) {                    }
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}
20. reduce scope of variables

~/myprog/foo.hpp                              ~/myprog/foo.cpp
namespace bar {                               #include <iostream>
  class Foo {                                 #include "foo.hpp"
  public:
     explicit Foo(int seed);                  namespace {
     void calc(int number);                     int myMagic(int a, int b) {
     int value() const;                           return a + b - 3 + 8 - 5;
     void print(const char * prefix) const;     }
  private:                                    }
     int value_;
  };                                          namespace bar {
}                                               Foo::Foo(int seed) : value_(seed) {
                                                }

                                                  void Foo::calc(int number) {
                                                    value_ += myMagic(value_, number);
                                                  }

~/myprog/main.cpp                                 int Foo::value() const {
                                                    return value_;
#include "foo.hpp"                                }
int main() {                                      void Foo::print(const char * prefix) const {
  bar::Foo foo(2);                                  std::cout << prefix << value_ << "n";
  const char * prefix = "the answer=";            }
  for(int i=0; i<4; i++) {                    }
    foo.calc(i);
  }
  foo.print(prefix);
  return 0;
}
20. reduce scope of variables

~/myprog/foo.hpp                              ~/myprog/foo.cpp
namespace bar {                               #include <iostream>
  class Foo {                                 #include "foo.hpp"
  public:
     explicit Foo(int seed);                  namespace {
     void calc(int number);                     int myMagic(int a, int b) {
     int value() const;                           return a + b - 3 + 8 - 5;
     void print(const char * prefix) const;     }
  private:                                    }
     int value_;
  };                                          namespace bar {
}                                               Foo::Foo(int seed) : value_(seed) {
                                                }

                                                  void Foo::calc(int number) {
                                                    value_ += myMagic(value_, number);
                                                  }

~/myprog/main.cpp                                 int Foo::value() const {
                                                    return value_;
#include "foo.hpp"                                }
int main() {                                      void Foo::print(const char * prefix) const {
  bar::Foo foo(2);                                  std::cout << prefix << value_ << "n";
  for(int i=0; i<4; i++) {                        }
    foo.calc(i);                              }
  }
  const char * prefix = "the answer=";
  foo.print(prefix);
  return 0;
}
21. for-loops in C++ are often not written like this

~/myprog/foo.hpp                               ~/myprog/foo.cpp
namespace bar {                                #include <iostream>
  class Foo {                                  #include "foo.hpp"
  public:
     explicit Foo(int seed);                   namespace {
     void calc(int number);                      int myMagic(int a, int b) {
     int value() const;                            return a + b - 3 + 8 - 5;
     void print(const char * prefix) const;      }
  private:                                     }
     int value_;
  };                                           namespace bar {
}                                                Foo::Foo(int seed) : value_(seed) {
                                                 }

                                                   void Foo::calc(int number) {
                                                     value_ += myMagic(value_, number);
                                                   }

~/myprog/main.cpp                                  int Foo::value() const {
                                                     return value_;
#include "foo.hpp"                                 }
int main() {                                       void Foo::print(const char * prefix) const {
  bar::Foo foo(2);                                   std::cout << prefix << value_ << "n";
  for(int i=0; i<4; i++) {                         }
    foo.calc(i);                               }
  }
  const char * prefix = "the answer=";
  foo.print(prefix);
  return 0;
}
21. for-loops in C++ are often not written like this

~/myprog/foo.hpp                               ~/myprog/foo.cpp
namespace bar {                                #include <iostream>
  class Foo {                                  #include "foo.hpp"
  public:
     explicit Foo(int seed);                   namespace {
     void calc(int number);                      int myMagic(int a, int b) {
     int value() const;                            return a + b - 3 + 8 - 5;
     void print(const char * prefix) const;      }
  private:                                     }
     int value_;
  };                                           namespace bar {
}                                                Foo::Foo(int seed) : value_(seed) {
                                                 }

                                                   void Foo::calc(int number) {
                                                     value_ += myMagic(value_, number);
                                                   }

~/myprog/main.cpp                                  int Foo::value() const {
                                                     return value_;
#include "foo.hpp"                                 }
int main() {                                       void Foo::print(const char * prefix) const {
  bar::Foo foo(2);                                   std::cout << prefix << value_ << "n";
  for (int i = 0; i != 4; ++i) {                   }
    foo.calc(i);                               }
  }
  const char * prefix = "the answer=";
  foo.print(prefix);
  return 0;
}
22. in C++ you do not need to explicitly return from main

~/myprog/foo.hpp                              ~/myprog/foo.cpp
namespace bar {                               #include <iostream>
  class Foo {                                 #include "foo.hpp"
  public:
     explicit Foo(int seed);                  namespace {
     void calc(int number);                     int myMagic(int a, int b) {
     int value() const;                           return a + b - 3 + 8 - 5;
     void print(const char * prefix) const;     }
  private:                                    }
     int value_;
  };                                          namespace bar {
}                                               Foo::Foo(int seed) : value_(seed) {
                                                }

                                                  void Foo::calc(int number) {
                                                    value_ += myMagic(value_, number);
                                                  }

~/myprog/main.cpp                                 int Foo::value() const {
                                                    return value_;
#include "foo.hpp"                                }
int main() {                                      void Foo::print(const char * prefix) const {
  bar::Foo foo(2);                                  std::cout << prefix << value_ << "n";
  for (int i = 0; i != 4; ++i) {                  }
    foo.calc(i);                              }
  }
  const char * prefix = "the answer=";
  foo.print(prefix);
  return 0;
}
22. in C++ you do not need to explicitly return from main

~/myprog/foo.hpp                              ~/myprog/foo.cpp
namespace bar {                               #include <iostream>
  class Foo {                                 #include "foo.hpp"
  public:
     explicit Foo(int seed);                  namespace {
     void calc(int number);                     int myMagic(int a, int b) {
     int value() const;                           return a + b - 3 + 8 - 5;
     void print(const char * prefix) const;     }
  private:                                    }
     int value_;
  };                                          namespace bar {
}                                               Foo::Foo(int seed) : value_(seed) {
                                                }

                                                  void Foo::calc(int number) {
                                                    value_ += myMagic(value_, number);
                                                  }

~/myprog/main.cpp                                 int Foo::value() const {
                                                    return value_;
#include "foo.hpp"                                }
int main() {                                      void Foo::print(const char * prefix) const {
  bar::Foo foo(2);                                  std::cout << prefix << value_ << "n";
  for (int i = 0; i != 4; ++i) {                  }
    foo.calc(i);                              }
  }
  const char * prefix = "the answer=";
  foo.print(prefix);
  return 0;
}
22. in C++ you do not need to explicitly return from main

~/myprog/foo.hpp                              ~/myprog/foo.cpp
namespace bar {                               #include <iostream>
  class Foo {                                 #include "foo.hpp"
  public:
     explicit Foo(int seed);                  namespace {
     void calc(int number);                     int myMagic(int a, int b) {
     int value() const;                           return a + b - 3 + 8 - 5;
     void print(const char * prefix) const;     }
  private:                                    }
     int value_;
  };                                          namespace bar {
}                                               Foo::Foo(int seed) : value_(seed) {
                                                }

                                                  void Foo::calc(int number) {
                                                    value_ += myMagic(value_, number);
                                                  }

~/myprog/main.cpp                                 int Foo::value() const {
                                                    return value_;
#include "foo.hpp"                                }
int main() {                                      void Foo::print(const char * prefix) const {
  bar::Foo foo(2);                                  std::cout << prefix << value_ << "n";
  for (int i = 0; i != 4; ++i) {                  }
    foo.calc(i);                              }
  }
  const char * prefix = "the answer=";
  foo.print(prefix);
}
23. inject side-effects if you must have them

~/myprog/foo.hpp                                ~/myprog/foo.cpp
namespace bar {                                 #include <iostream>
  class Foo {                                   #include "foo.hpp"
  public:
     explicit Foo(int seed);                    namespace {
     void calc(int number);                       int myMagic(int a, int b) {
     int value() const;                             return a + b - 3 + 8 - 5;
     void print(const char * prefix) const;       }
  private:                                      }
     int value_;
  };                                            namespace bar {
}                                                 Foo::Foo(int seed) : value_(seed) {
                                                  }

                                                    void Foo::calc(int number) {
                                                      value_ += myMagic(value_, number);
                                                    }

~/myprog/main.cpp                                   int Foo::value() const {
                                                      return value_;
#include "foo.hpp"                                  }
int main() {                                        void Foo::print(const char * prefix) const {
  bar::Foo foo(2);                                    std::cout << prefix << value_ << "n";
  for (int i = 0; i != 4; ++i) {                    }
    foo.calc(i);                                }
  }
  const char * prefix = "the answer=";
  foo.print(prefix);
}
23. inject side-effects if you must have them

~/myprog/foo.hpp                                ~/myprog/foo.cpp
namespace bar {                                 #include <ostream>
  class Foo {                                   #include "foo.hpp"
  public:
     explicit Foo(int seed);                    namespace {
     void calc(int number);                       int myMagic(int a, int b) {
     int value() const;                             return a + b - 3 + 8 - 5;
     void print(std::ostream & out,               }
                 const char * prefix) const;    }
  private:
     int value_;                                namespace bar {
  };                                              Foo::Foo(int seed) : value_(seed) {
}                                                 }

                                                    void Foo::calc(int number) {
                                                      value_ += myMagic(value_, number);
                                                    }

~/myprog/main.cpp                                   int Foo::value() const {
                                                      return value_;
#include <iostream>                                 }
#include "foo.hpp"
                                                    void Foo::print(std::ostream & out,
int main() {                                                        const char * prefix) const {
  bar::Foo foo(2);                                    out << prefix << value_ << "n";
  for (int i = 0; i != 4; ++i) {                    }
    foo.calc(i);                                }
  }
  const char * prefix = "the answer=";
  foo.print(std::cout, prefix);
}
24. make sure headers compile by itself

~/myprog/foo.hpp                               ~/myprog/foo.cpp
namespace bar {                                #include <ostream>
  class Foo {                                  #include "foo.hpp"
  public:
     explicit Foo(int seed);                   namespace {
     void calc(int number);                      int myMagic(int a, int b) {
     int value() const;                            return a + b - 3 + 8 - 5;
     void print(std::ostream & out,              }
                 const char * prefix) const;   }
  private:
     int value_;                               namespace bar {
  };                                             Foo::Foo(int seed) : value_(seed) {
}                                                }

                                                   void Foo::calc(int number) {
                                                     value_ += myMagic(value_, number);
                                                   }

~/myprog/main.cpp                                  int Foo::value() const {
                                                     return value_;
#include <iostream>                                }
#include "foo.hpp"
                                                   void Foo::print(std::ostream & out,
int main() {                                                       const char * prefix) const {
  bar::Foo foo(2);                                   out << prefix << value_ << "n";
  for (int i = 0; i != 4; ++i) {                   }
    foo.calc(i);                               }
  }
  const char * prefix = "the answer=";
  foo.print(std::cout, prefix);
}
24. make sure headers compile by itself

~/myprog/foo.hpp                               ~/myprog/foo.cpp
#include <iostream>                            #include <ostream>
                                               #include "foo.hpp"
namespace bar {
  class Foo {                                  namespace {
  public:                                        int myMagic(int a, int b) {
     explicit Foo(int seed);                       return a + b - 3 + 8 - 5;
     void calc(int number);                      }
     int value() const;                        }
     void print(std::ostream & out,
                 const char * prefix) const;   namespace bar {
  private:                                       Foo::Foo(int seed) : value_(seed) {
     int value_;                                 }
  };
}                                                  void Foo::calc(int number) {
                                                     value_ += myMagic(value_, number);
                                                   }

~/myprog/main.cpp                                  int Foo::value() const {
                                                     return value_;
#include <iostream>                                }
#include "foo.hpp"
                                                   void Foo::print(std::ostream & out,
int main() {                                                       const char * prefix) const {
  bar::Foo foo(2);                                   out << prefix << value_ << "n";
  for (int i = 0; i != 4; ++i) {                   }
    foo.calc(i);                               }
  }
  const char * prefix = "the answer=";
  foo.print(std::cout, prefix);
}
25. include your own header file first, standard libraries last

~/myprog/foo.hpp                               ~/myprog/foo.cpp
#include <iostream>                            #include <ostream>
                                               #include "foo.hpp"
namespace bar {
  class Foo {                                  namespace {
  public:                                        int myMagic(int a, int b) {
     explicit Foo(int seed);                       return a + b - 3 + 8 - 5;
     void calc(int number);                      }
     int value() const;                        }
     void print(std::ostream & out,
                 const char * prefix) const;   namespace bar {
  private:                                       Foo::Foo(int seed) : value_(seed) {
     int value_;                                 }
  };
}                                                  void Foo::calc(int number) {
                                                     value_ += myMagic(value_, number);
                                                   }

~/myprog/main.cpp                                  int Foo::value() const {
                                                     return value_;
#include <iostream>                                }
#include "foo.hpp"
                                                   void Foo::print(std::ostream & out,
int main() {                                                       const char * prefix) const {
  bar::Foo foo(2);                                   out << prefix << value_ << "n";
  for (int i = 0; i != 4; ++i) {                   }
    foo.calc(i);                               }
  }
  const char * prefix = "the answer=";
  foo.print(std::cout, prefix);
}
25. include your own header file first, standard libraries last

~/myprog/foo.hpp                               ~/myprog/foo.cpp
#include <iostream>                            #include "foo.hpp"
                                               #include <ostream>
namespace bar {
  class Foo {                                  namespace {
  public:                                        int myMagic(int a, int b) {
     explicit Foo(int seed);                       return a + b - 3 + 8 - 5;
     void calc(int number);                      }
     int value() const;                        }
     void print(std::ostream & out,
                 const char * prefix) const;   namespace bar {
  private:                                       Foo::Foo(int seed) : value_(seed) {
     int value_;                                 }
  };
}                                                  void Foo::calc(int number) {
                                                     value_ += myMagic(value_, number);
                                                   }

~/myprog/main.cpp                                  int Foo::value() const {
                                                     return value_;
#include "foo.hpp"                                 }
#include <iostream>
                                                   void Foo::print(std::ostream & out,
int main() {                                                       const char * prefix) const {
  bar::Foo foo(2);                                   out << prefix << value_ << "n";
  for (int i = 0; i != 4; ++i) {                   }
    foo.calc(i);                               }
  }
  const char * prefix = "the answer=";
  foo.print(std::cout, prefix);
}
26. prefer forward declarations in header files

~/myprog/foo.hpp                               ~/myprog/foo.cpp
#include <iostream>                            #include "foo.hpp"
                                               #include <ostream>
namespace bar {
  class Foo {                                  namespace {
  public:                                        int myMagic(int a, int b) {
     explicit Foo(int seed);                       return a + b - 3 + 8 - 5;
     void calc(int number);                      }
     int value() const;                        }
     void print(std::ostream & out,
                 const char * prefix) const;   namespace bar {
  private:                                       Foo::Foo(int seed) : value_(seed) {
     int value_;                                 }
  };
}                                                  void Foo::calc(int number) {
                                                     value_ += myMagic(value_, number);
                                                   }

~/myprog/main.cpp                                  int Foo::value() const {
                                                     return value_;
#include "foo.hpp"                                 }
#include <iostream>
                                                   void Foo::print(std::ostream & out,
int main() {                                                       const char * prefix) const {
  bar::Foo foo(2);                                   out << prefix << value_ << "n";
  for (int i = 0; i != 4; ++i) {                   }
    foo.calc(i);                               }
  }
  const char * prefix = "the answer=";
  foo.print(std::cout, prefix);
}
26. prefer forward declarations in header files

~/myprog/foo.hpp                               ~/myprog/foo.cpp
#include <iosfwd>                              #include "foo.hpp"
                                               #include <ostream>
namespace bar {
  class Foo {                                  namespace {
  public:                                        int myMagic(int a, int b) {
     explicit Foo(int seed);                       return a + b - 3 + 8 - 5;
     void calc(int number);                      }
     int value() const;                        }
     void print(std::ostream & out,
                 const char * prefix) const;   namespace bar {
  private:                                       Foo::Foo(int seed) : value_(seed) {
     int value_;                                 }
  };
}                                                  void Foo::calc(int number) {
                                                     value_ += myMagic(value_, number);
                                                   }

~/myprog/main.cpp                                  int Foo::value() const {
                                                     return value_;
#include "foo.hpp"                                 }
#include <iostream>
                                                   void Foo::print(std::ostream & out,
int main() {                                                       const char * prefix) const {
  bar::Foo foo(2);                                   out << prefix << value_ << "n";
  for (int i = 0; i != 4; ++i) {                   }
    foo.calc(i);                               }
  }
  const char * prefix = "the answer=";
  foo.print(std::cout, prefix);
}
27. don't need braces here

~/myprog/foo.hpp                               ~/myprog/foo.cpp
#include <iosfwd>                              #include "foo.hpp"
                                               #include <ostream>
namespace bar {
  class Foo {                                  namespace {
  public:                                        int myMagic(int a, int b) {
     explicit Foo(int seed);                       return a + b - 3 + 8 - 5;
     void calc(int number);                      }
     int value() const;                        }
     void print(std::ostream & out,
                 const char * prefix) const;   namespace bar {
  private:                                       Foo::Foo(int seed) : value_(seed) {
     int value_;                                 }
  };
}                                                  void Foo::calc(int number) {
                                                     value_ += myMagic(value_, number);
                                                   }

~/myprog/main.cpp                                  int Foo::value() const {
                                                     return value_;
#include "foo.hpp"                                 }
#include <iostream>
                                                   void Foo::print(std::ostream & out,
int main() {                                                       const char * prefix) const {
  bar::Foo foo(2);                                   out << prefix << value_ << "n";
  for (int i = 0; i != 4; ++i) {                   }
    foo.calc(i);                               }
  }
  const char * prefix = "the answer=";
  foo.print(std::cout, prefix);
}
27. don't need braces here

~/myprog/foo.hpp                               ~/myprog/foo.cpp
#include <iosfwd>                              #include "foo.hpp"
                                               #include <ostream>
namespace bar {
  class Foo {                                  namespace {
  public:                                        int myMagic(int a, int b) {
     explicit Foo(int seed);                       return a + b - 3 + 8 - 5;
     void calc(int number);                      }
     int value() const;                        }
     void print(std::ostream & out,
                 const char * prefix) const;   namespace bar {
  private:                                       Foo::Foo(int seed) : value_(seed) {
     int value_;                                 }
  };
}                                                  void Foo::calc(int number) {
                                                     value_ += myMagic(value_, number);
                                                   }

~/myprog/main.cpp                                  int Foo::value() const {
                                                     return value_;
#include "foo.hpp"                                 }
#include <iostream>
                                                   void Foo::print(std::ostream & out,
int main() {                                                       const char * prefix) const {
  bar::Foo foo(2);                                   out << prefix << value_ << "n";
  for (int i = 0; i != 4; ++i)                     }
    foo.calc(i);                               }
  const char * prefix = "the answer=";
  foo.print(std::cout, prefix);
}
28. avoid side-effects if you can, prefer free-standing functions

~/myprog/foo.hpp                               ~/myprog/foo.cpp
#include <iosfwd>                              #include "foo.hpp"
                                               #include <ostream>
namespace bar {
  class Foo {                                  namespace {
  public:                                        int myMagic(int a, int b) {
     explicit Foo(int seed);                       return a + b - 3 + 8 - 5;
     void calc(int number);                      }
     int value() const;                        }
     void print(std::ostream & out,
                 const char * prefix) const;   namespace bar {
  private:                                       Foo::Foo(int seed) : value_(seed) {
     int value_;                                 }
  };
}                                                  void Foo::calc(int number) {
                                                     value_ += myMagic(value_, number);
                                                   }

~/myprog/main.cpp                                  int Foo::value() const {
                                                     return value_;
#include "foo.hpp"                                 }
#include <iostream>
                                                   void Foo::print(std::ostream & out,
int main() {                                                       const char * prefix) const {
  bar::Foo foo(2);                                   out << prefix << value_ << "n";
  for (int i = 0; i != 4; ++i)                     }
    foo.calc(i);                               }
  const char * prefix = "the answer=";
  foo.print(std::cout, prefix);
}
28. avoid side-effects if you can, prefer free-standing functions

~/myprog/foo.hpp                             ~/myprog/foo.cpp
#include <iosfwd>                            #include "foo.hpp"
                                             #include <ostream>
namespace bar {
  class Foo {                                namespace {
  public:                                      int myMagic(int a, int b) {
     explicit Foo(int seed);                     return a + b - 3 + 8 - 5;
     void calc(int number);                    }
     int value() const;                      }
  private:
     int value_;                             namespace bar {
  };                                           Foo::Foo(int seed) : value_(seed) {
  void print(std::ostream & out,               }
              const char * prefix,
              const Foo & foo);                  void Foo::calc(int number) {
}                                                  value_ += myMagic(value_, number);
                                                 }

~/myprog/main.cpp                                int Foo::value() const {
                                                   return value_;
#include "foo.hpp"                               }
#include <iostream>
                                                 void print(std::ostream & out,
int main() {                                                const char * prefix,
  bar::Foo foo(2);                                          const Foo & foo) {
  for (int i = 0; i != 4; ++i)                     out << prefix << foo.value() << "n";
    foo.calc(i);                                 }
  const char * prefix = "the answer=";       }
  print(std::cout, prefix, foo);
}
29. do not open a namespace when implementing free-standing functions

~/myprog/foo.hpp                         ~/myprog/foo.cpp
#include <iosfwd>                        #include "foo.hpp"
                                         #include <ostream>
namespace bar {
  class Foo {                            namespace {
  public:                                  int myMagic(int a, int b) {
     explicit Foo(int seed);                 return a + b - 3 + 8 - 5;
     void calc(int number);                }
     int value() const;                  }
  private:
     int value_;                         namespace bar {
  };                                       Foo::Foo(int seed) : value_(seed) {
  void print(std::ostream & out,           }
              const char * prefix,
              const Foo & foo);              void Foo::calc(int number) {
}                                              value_ += myMagic(value_, number);
                                             }

~/myprog/main.cpp                            int Foo::value() const {
                                               return value_;
#include "foo.hpp"                           }
#include <iostream>
                                             void print(std::ostream & out,
int main() {                                            const char * prefix,
  bar::Foo foo(2);                                      const Foo & foo) {
  for (int i = 0; i != 4; ++i)                 out << prefix << foo.value() << "n";
    foo.calc(i);                             }
  const char * prefix = "the answer=";   }
  print(std::cout, prefix, foo);
}
29. do not open a namespace when implementing free-standing functions

~/myprog/foo.hpp                         ~/myprog/foo.cpp
#include <iosfwd>                        #include "foo.hpp"
                                         #include <ostream>
namespace bar {
  class Foo {                            namespace {
  public:                                  int myMagic(int a, int b) {
     explicit Foo(int seed);                 return a + b - 3 + 8 - 5;
     void calc(int number);                }
     int value() const;                  }
  private:
     int value_;                         namespace bar {
  };                                       Foo::Foo(int seed) : value_(seed) {
  void print(std::ostream & out,           }
              const char * prefix,
              const Foo & foo);              void Foo::calc(int number) {
}                                              value_ += myMagic(value_, number);
                                             }

~/myprog/main.cpp                            int Foo::value() const {
                                               return value_;
#include "foo.hpp"                           }
#include <iostream>                      }
int main() {                             void bar::print(std::ostream & out,
  bar::Foo foo(2);                                       const char * prefix,
  for (int i = 0; i != 4; ++i)                           const bar::Foo & foo) {
    foo.calc(i);                           out << prefix << foo.value() << "n";
  const char * prefix = "the answer=";   }
  print(std::cout, prefix, foo);
}
30. operator overloading is sometimes a nice thing

~/myprog/foo.hpp                           ~/myprog/foo.cpp
#include <iosfwd>                          #include "foo.hpp"
                                           #include <ostream>
namespace bar {
  class Foo {                              namespace {
  public:                                    int myMagic(int a, int b) {
     explicit Foo(int seed);                   return a + b - 3 + 8 - 5;
     void calc(int number);                  }
     int value() const;                    }
  private:
     int value_;                           namespace bar {
  };                                         Foo::Foo(int seed) : value_(seed) {
  void print(std::ostream & out,             }
              const char * prefix,
              const Foo & foo);                void Foo::calc(int number) {
}                                                value_ += myMagic(value_, number);
                                               }

~/myprog/main.cpp                              int Foo::value() const {
                                                 return value_;
#include "foo.hpp"                             }
#include <iostream>                        }
int main() {                               void bar::print(std::ostream & out,
  bar::Foo foo(2);                                         const char * prefix,
  for (int i = 0; i != 4; ++i)                             const bar::Foo & foo) {
    foo.calc(i);                             out << prefix << foo.value() << "n";
  const char * prefix = "the answer=";     }
  print(std::cout, prefix, foo);
}
C++ idioms by example (Nov 2008)
C++ idioms by example (Nov 2008)
C++ idioms by example (Nov 2008)
C++ idioms by example (Nov 2008)
C++ idioms by example (Nov 2008)
C++ idioms by example (Nov 2008)
C++ idioms by example (Nov 2008)
C++ idioms by example (Nov 2008)
C++ idioms by example (Nov 2008)
C++ idioms by example (Nov 2008)
C++ idioms by example (Nov 2008)

More Related Content

What's hot

Cours structures des données (langage c)
Cours structures des données (langage c)Cours structures des données (langage c)
Cours structures des données (langage c)rezgui mohamed
 
TDD in C - Recently Used List Kata
TDD in C - Recently Used List KataTDD in C - Recently Used List Kata
TDD in C - Recently Used List KataOlve Maudal
 
Chapitre4: Pointeurs et références
Chapitre4: Pointeurs et références Chapitre4: Pointeurs et références
Chapitre4: Pointeurs et références Aziz Darouichi
 
Function in c program
Function in c programFunction in c program
Function in c programumesh patil
 
OOP in C++
OOP in C++OOP in C++
OOP in C++ppd1961
 
Présentation de Django @ Orange Labs (FR)
Présentation de Django @ Orange Labs (FR)Présentation de Django @ Orange Labs (FR)
Présentation de Django @ Orange Labs (FR)Martin Latrille
 
Working Remotely (via SSH) Rocks!
Working Remotely (via SSH) Rocks!Working Remotely (via SSH) Rocks!
Working Remotely (via SSH) Rocks!Kent Chen
 
Q2.12: Debugging with GDB
Q2.12: Debugging with GDBQ2.12: Debugging with GDB
Q2.12: Debugging with GDBLinaro
 
Chapitre6: Surcharge des opérateurs
Chapitre6:  Surcharge des opérateursChapitre6:  Surcharge des opérateurs
Chapitre6: Surcharge des opérateursAziz Darouichi
 
Memory allocation in c
Memory allocation in cMemory allocation in c
Memory allocation in cPrabhu Govind
 
Programmation orientée objet : Object, classe et encapsulation
Programmation orientée objet : Object, classe et encapsulationProgrammation orientée objet : Object, classe et encapsulation
Programmation orientée objet : Object, classe et encapsulationECAM Brussels Engineering School
 

What's hot (20)

Cours structures des données (langage c)
Cours structures des données (langage c)Cours structures des données (langage c)
Cours structures des données (langage c)
 
GDB Rocks!
GDB Rocks!GDB Rocks!
GDB Rocks!
 
Deep C
Deep CDeep C
Deep C
 
TDD in C - Recently Used List Kata
TDD in C - Recently Used List KataTDD in C - Recently Used List Kata
TDD in C - Recently Used List Kata
 
Chapitre4: Pointeurs et références
Chapitre4: Pointeurs et références Chapitre4: Pointeurs et références
Chapitre4: Pointeurs et références
 
Rust vs C++
Rust vs C++Rust vs C++
Rust vs C++
 
Function in c program
Function in c programFunction in c program
Function in c program
 
The Internals of "Hello World" Program
The Internals of "Hello World" ProgramThe Internals of "Hello World" Program
The Internals of "Hello World" Program
 
C function presentation
C function presentationC function presentation
C function presentation
 
file
filefile
file
 
OOP in C++
OOP in C++OOP in C++
OOP in C++
 
Présentation de Django @ Orange Labs (FR)
Présentation de Django @ Orange Labs (FR)Présentation de Django @ Orange Labs (FR)
Présentation de Django @ Orange Labs (FR)
 
Working Remotely (via SSH) Rocks!
Working Remotely (via SSH) Rocks!Working Remotely (via SSH) Rocks!
Working Remotely (via SSH) Rocks!
 
Q2.12: Debugging with GDB
Q2.12: Debugging with GDBQ2.12: Debugging with GDB
Q2.12: Debugging with GDB
 
Chapitre6: Surcharge des opérateurs
Chapitre6:  Surcharge des opérateursChapitre6:  Surcharge des opérateurs
Chapitre6: Surcharge des opérateurs
 
Memory allocation in c
Memory allocation in cMemory allocation in c
Memory allocation in c
 
Files and streams
Files and streamsFiles and streams
Files and streams
 
Intro to c++
Intro to c++Intro to c++
Intro to c++
 
Function & Recursion
Function & RecursionFunction & Recursion
Function & Recursion
 
Programmation orientée objet : Object, classe et encapsulation
Programmation orientée objet : Object, classe et encapsulationProgrammation orientée objet : Object, classe et encapsulation
Programmation orientée objet : Object, classe et encapsulation
 

Viewers also liked

Viewers also liked (20)

How A Compiler Works: GNU Toolchain
How A Compiler Works: GNU ToolchainHow A Compiler Works: GNU Toolchain
How A Compiler Works: GNU Toolchain
 
C++11
C++11C++11
C++11
 
Intro. to prog. c++
Intro. to prog. c++Intro. to prog. c++
Intro. to prog. c++
 
Singleton is not_the_only_pattern
Singleton is not_the_only_patternSingleton is not_the_only_pattern
Singleton is not_the_only_pattern
 
Esoft Metro Campus - Programming with C++
Esoft Metro Campus - Programming with C++Esoft Metro Campus - Programming with C++
Esoft Metro Campus - Programming with C++
 
Top C Language Interview Questions and Answer
Top C Language Interview Questions and AnswerTop C Language Interview Questions and Answer
Top C Language Interview Questions and Answer
 
C++ Programming Language
C++ Programming Language C++ Programming Language
C++ Programming Language
 
Penerjemahan idiom
Penerjemahan idiomPenerjemahan idiom
Penerjemahan idiom
 
iOS 6 Exploitation 280 days later
iOS 6 Exploitation 280 days lateriOS 6 Exploitation 280 days later
iOS 6 Exploitation 280 days later
 
Dconf2015 d2 t4
Dconf2015 d2 t4Dconf2015 d2 t4
Dconf2015 d2 t4
 
Linked lists
Linked listsLinked lists
Linked lists
 
Data mining
Data miningData mining
Data mining
 
C Standards: main()
C Standards: main()C Standards: main()
C Standards: main()
 
Functional Leap of Faith (Keynote at JDay Lviv 2014)
Functional Leap of Faith (Keynote at JDay Lviv 2014)Functional Leap of Faith (Keynote at JDay Lviv 2014)
Functional Leap of Faith (Keynote at JDay Lviv 2014)
 
C++ TUTORIAL 8
C++ TUTORIAL 8C++ TUTORIAL 8
C++ TUTORIAL 8
 
What Can Compilers Do for Us?
What Can Compilers Do for Us?What Can Compilers Do for Us?
What Can Compilers Do for Us?
 
Operators in C Programming
Operators in C ProgrammingOperators in C Programming
Operators in C Programming
 
Three Optimization Tips for C++
Three Optimization Tips for C++Three Optimization Tips for C++
Three Optimization Tips for C++
 
Data structures & algorithms lecture 3
Data structures & algorithms lecture 3Data structures & algorithms lecture 3
Data structures & algorithms lecture 3
 
Escape sequence in c part 1
Escape sequence in c   part 1Escape sequence in c   part 1
Escape sequence in c part 1
 

Similar to C++ idioms by example (Nov 2008)

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
 
COSCUP2012: How to write a bash script like the python?
COSCUP2012: How to write a bash script like the python?COSCUP2012: How to write a bash script like the python?
COSCUP2012: How to write a bash script like the python?Lloyd Huang
 
Go serving: Building server app with go
Go serving: Building server app with goGo serving: Building server app with go
Go serving: Building server app with goHean Hong Leong
 
ฟังก์ชั่นย่อยและโปรแกรมมาตรฐาน ม. 6 1
ฟังก์ชั่นย่อยและโปรแกรมมาตรฐาน ม. 6  1ฟังก์ชั่นย่อยและโปรแกรมมาตรฐาน ม. 6  1
ฟังก์ชั่นย่อยและโปรแกรมมาตรฐาน ม. 6 1Little Tukta Lita
 
ekb.py - Python VS ...
ekb.py - Python VS ...ekb.py - Python VS ...
ekb.py - Python VS ...it-people
 
Using Flow-based programming to write tools and workflows for Scientific Comp...
Using Flow-based programming to write tools and workflows for Scientific Comp...Using Flow-based programming to write tools and workflows for Scientific Comp...
Using Flow-based programming to write tools and workflows for Scientific Comp...Samuel Lampa
 
C ISRO Debugging
C ISRO DebuggingC ISRO Debugging
C ISRO Debuggingsplix757
 
Golang iran - tutorial go programming language - Preliminary
Golang iran - tutorial  go programming language - PreliminaryGolang iran - tutorial  go programming language - Preliminary
Golang iran - tutorial go programming language - Preliminarygo-lang
 
Cbse question-paper-computer-science-2009
Cbse question-paper-computer-science-2009Cbse question-paper-computer-science-2009
Cbse question-paper-computer-science-2009Deepak Singh
 
Inheritance compiler support
Inheritance compiler supportInheritance compiler support
Inheritance compiler supportSyed Zaid Irshad
 
Virtual function
Virtual functionVirtual function
Virtual functionharman kaur
 
Threads and Callbacks for Embedded Python
Threads and Callbacks for Embedded PythonThreads and Callbacks for Embedded Python
Threads and Callbacks for Embedded PythonYi-Lung Tsai
 
C++aptitude questions and answers
C++aptitude questions and answersC++aptitude questions and answers
C++aptitude questions and answerssheibansari
 
I need a complete working code for a solution to this problem using .pdf
I need a complete working code for a solution to this problem using .pdfI need a complete working code for a solution to this problem using .pdf
I need a complete working code for a solution to this problem using .pdfmichaelazach6427
 
Phyton Learning extracts
Phyton Learning extracts Phyton Learning extracts
Phyton Learning extracts Pavan Babu .G
 
Computer science-2010-cbse-question-paper
Computer science-2010-cbse-question-paperComputer science-2010-cbse-question-paper
Computer science-2010-cbse-question-paperDeepak Singh
 

Similar to C++ idioms by example (Nov 2008) (20)

Sbaw091006
Sbaw091006Sbaw091006
Sbaw091006
 
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
 
COSCUP2012: How to write a bash script like the python?
COSCUP2012: How to write a bash script like the python?COSCUP2012: How to write a bash script like the python?
COSCUP2012: How to write a bash script like the python?
 
Go serving: Building server app with go
Go serving: Building server app with goGo serving: Building server app with go
Go serving: Building server app with go
 
ฟังก์ชั่นย่อยและโปรแกรมมาตรฐาน ม. 6 1
ฟังก์ชั่นย่อยและโปรแกรมมาตรฐาน ม. 6  1ฟังก์ชั่นย่อยและโปรแกรมมาตรฐาน ม. 6  1
ฟังก์ชั่นย่อยและโปรแกรมมาตรฐาน ม. 6 1
 
ekb.py - Python VS ...
ekb.py - Python VS ...ekb.py - Python VS ...
ekb.py - Python VS ...
 
Using Flow-based programming to write tools and workflows for Scientific Comp...
Using Flow-based programming to write tools and workflows for Scientific Comp...Using Flow-based programming to write tools and workflows for Scientific Comp...
Using Flow-based programming to write tools and workflows for Scientific Comp...
 
C ISRO Debugging
C ISRO DebuggingC ISRO Debugging
C ISRO Debugging
 
Golang iran - tutorial go programming language - Preliminary
Golang iran - tutorial  go programming language - PreliminaryGolang iran - tutorial  go programming language - Preliminary
Golang iran - tutorial go programming language - Preliminary
 
Cbse question-paper-computer-science-2009
Cbse question-paper-computer-science-2009Cbse question-paper-computer-science-2009
Cbse question-paper-computer-science-2009
 
Function in C program
Function in C programFunction in C program
Function in C program
 
Functions in C
Functions in CFunctions in C
Functions in C
 
Inheritance compiler support
Inheritance compiler supportInheritance compiler support
Inheritance compiler support
 
C++ Chapter IV
C++ Chapter IVC++ Chapter IV
C++ Chapter IV
 
Virtual function
Virtual functionVirtual function
Virtual function
 
Threads and Callbacks for Embedded Python
Threads and Callbacks for Embedded PythonThreads and Callbacks for Embedded Python
Threads and Callbacks for Embedded Python
 
C++aptitude questions and answers
C++aptitude questions and answersC++aptitude questions and answers
C++aptitude questions and answers
 
I need a complete working code for a solution to this problem using .pdf
I need a complete working code for a solution to this problem using .pdfI need a complete working code for a solution to this problem using .pdf
I need a complete working code for a solution to this problem using .pdf
 
Phyton Learning extracts
Phyton Learning extracts Phyton Learning extracts
Phyton Learning extracts
 
Computer science-2010-cbse-question-paper
Computer science-2010-cbse-question-paperComputer science-2010-cbse-question-paper
Computer science-2010-cbse-question-paper
 

Recently uploaded

🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Evaluating the top large language models.pdf
Evaluating the top large language models.pdfEvaluating the top large language models.pdf
Evaluating the top large language models.pdfChristopherTHyatt
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 

Recently uploaded (20)

🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Evaluating the top large language models.pdf
Evaluating the top large language models.pdfEvaluating the top large language models.pdf
Evaluating the top large language models.pdf
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 

C++ idioms by example (Nov 2008)

  • 1. C++ Idioms by Example, lesson 1 I Introducing some very basic C++ idioms, rules, guidelines and best practices h a Olve Maudal oma@pvv.org November 2008 Disclaimer: most of the items I will discuss here are indeed idioms and conventions of the C++ language, something that most experts will agree on. However some of the items are based on an ecolect – a programming style that is unique for a limited group of developers. There are also a few items based on my idiolect, which is a programming style that I believe in. And you may argue that one or two things I suggest here are just plain idiotic... My intention is not to tell you how to do C++ programming. I hope to use this presentation as a catalyst for discussion, therefor I have also included some controversial issues. Ignite your flamethrower. Choose your battles!
  • 2. Please criticise this program. ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" int _value; int my_magic(int a, int b); using namespace std; public: Foo(int seed); namespace bar { int calc(int number = 7); Foo::Foo(int seed) { int getValue() { _value = seed; return _value; } } void print(char* prefix); int Foo::my_magic(int a, int b) { }; return a + b - 3 + 8 - 5; } } int Foo::calc(int number) { int result = my_magic(_value, number); _value += result; ~/myprog/main.cpp return result; } #include "foo.hpp" void Foo::print(char *prefix) { int main() { cout << prefix << _value << "n"; bar::Foo foo(2); } char * prefix = "the answer="; } for(int i=0; i<4; i++) { foo.calc(i); Please criticise this program } foo.print(prefix); return 0; } Spend 5-10 minutes to read through the code. Imagine that this is a piece of code that you found in a larger codebase. Criticise everything you see, ... apart from the fact that it is a contrived, incorrect and stupid program that does not do anything useful, and is probably better written in Python as print “the $ cd ~/myprog answer=42” (and do not spend time on the implmentation of my_magic) $ g++ foo.cpp main.cpp && ./a.out the answer=43
  • 3. What do you see in this code? Happiness?
  • 4.
  • 6.
  • 7. I see trouble. It looks like the code has been written by someone with little experience in C++, or even worse, by someone who does not care... Large amount of this kind of code will make your codebase rot. But, once you start to believe - it is time to defeat the deteriorating agents
  • 8.
  • 9. ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" int _value; int my_magic(int a, int b); using namespace std; public: Foo(int seed); namespace bar { int calc(int number = 7); Foo::Foo(int seed) { int getValue() { _value = seed; return _value; } } void print(char* prefix); int Foo::my_magic(int a, int b) { }; return a + b - 3 + 8 - 5; } } int Foo::calc(int number) { int result = my_magic(_value, number); _value += result; ~/myprog/main.cpp return result; } #include "foo.hpp" void Foo::print(char *prefix) { int main() { cout << prefix << _value << "n"; bar::Foo foo(2); } char * prefix = "the answer="; } for(int i=0; i<4; i++) { foo.calc(i); } foo.print(prefix); return 0; } $ cd ~/myprog $ g++ foo.cpp main.cpp && ./a.out the answer=43
  • 10. 1. always compile with high warning level, and treat warnings as errors ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" int _value; int my_magic(int a, int b); using namespace std; public: Foo(int seed); namespace bar { int calc(int number = 7); Foo::Foo(int seed) { int getValue() { _value = seed; return _value; } } void print(char* prefix); int Foo::my_magic(int a, int b) { }; return a + b - 3 + 8 - 5; } } int Foo::calc(int number) { int result = my_magic(_value, number); _value += result; ~/myprog/main.cpp return result; } #include "foo.hpp" void Foo::print(char *prefix) { int main() { cout << prefix << _value << "n"; bar::Foo foo(2); } char * prefix = "the answer="; } for(int i=0; i<4; i++) { foo.calc(i); } foo.print(prefix); return 0; } $ cd ~/myprog $ g++ -Wall -Wextra -pedantic -Werror foo.cpp main.cpp && ./a.out the answer=43
  • 11. 2. always use tools to support the building process ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" int _value; int my_magic(int a, int b); using namespace std; public: Foo(int seed); ~/myprog/Makefile int calc(int number = 7); namespace bar { Foo::Foo(int seed) { int getValue() { _value = seed; return _value; CPPFLAGS=-Wall -Wextra } -pedantic -Werror } LDFLAGS= void print(char* prefix); int Foo::my_magic(int a, int b) { }; return a + b - 3 + 8 - 5; } all: myprog } int Foo::calc(int number) { myprog: foo.o main.o int result = my_magic(_value, number); ~/myprog/main.cpp $(CXX) -o $@ $(LDFLAGS) $+ result; _value += return result; } #include "foo.hpp" clean: void Foo::print(char *prefix) { int main() { rm -f foo.o main.o myprog prefix << _value << cout << "n"; bar::Foo foo(2); } char * prefix = "the answer="; } for(int i=0; i<4; i++) { foo.calc(i); } foo.print(prefix); return 0; } $ cd ~/myprog $ make $ ./myprog the answer=43
  • 12. 3. do not _prefix member variables, use postfix_ if you must ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" int _value; int my_magic(int a, int b); using namespace std; public: Foo(int seed); namespace bar { int calc(int number = 7); Foo::Foo(int seed) { int getValue() { _value = seed; return _value; } } void print(char* prefix); int Foo::my_magic(int a, int b) { }; return a + b - 3 + 8 - 5; } } int Foo::calc(int number) { int result = my_magic(_value, number); _value += result; ~/myprog/main.cpp return result; } #include "foo.hpp" void Foo::print(char *prefix) { int main() { cout << prefix << _value << "n"; bar::Foo foo(2); } char * prefix = "the answer="; } for(int i=0; i<4; i++) { foo.calc(i); } foo.print(prefix); return 0; }
  • 13. 3. do not _prefix member variables, use postfix_ if you must ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" int value_; int my_magic(int a, int b); using namespace std; public: Foo(int seed); namespace bar { int calc(int number = 7); Foo::Foo(int seed) { int getValue() { value_ = seed; return value_; } } void print(char* prefix); int Foo::my_magic(int a, int b) { }; return a + b - 3 + 8 - 5; } } int Foo::calc(int number) { int result = my_magic(value_, number); value_ += result; ~/myprog/main.cpp return result; } #include "foo.hpp" void Foo::print(char *prefix) { int main() { cout << prefix << value_ << "n"; bar::Foo foo(2); } char * prefix = "the answer="; } for(int i=0; i<4; i++) { foo.calc(i); } foo.print(prefix); return 0; }
  • 14. 4. public stuff should be declared first, then the private stuff ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" int value_; int my_magic(int a, int b); using namespace std; public: Foo(int seed); namespace bar { int calc(int number = 7); Foo::Foo(int seed) { int getValue() { value_ = seed; return value_; } } void print(char* prefix); int Foo::my_magic(int a, int b) { }; return a + b - 3 + 8 - 5; } } int Foo::calc(int number) { int result = my_magic(value_, number); value_ += result; ~/myprog/main.cpp return result; } #include "foo.hpp" void Foo::print(char *prefix) { int main() { cout << prefix << value_ << "n"; bar::Foo foo(2); } char * prefix = "the answer="; } for(int i=0; i<4; i++) { foo.calc(i); } foo.print(prefix); return 0; }
  • 15. 4. public stuff should be declared first, then the private stuff ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: Foo(int seed); using namespace std; int calc(int number = 7); int getValue() { namespace bar { return value_; Foo::Foo(int seed) { } value_ = seed; void print(char* prefix); } private: int value_; int Foo::my_magic(int a, int b) { int my_magic(int a, int b); return a + b - 3 + 8 - 5; }; } } int Foo::calc(int number) { int result = my_magic(value_, number); value_ += result; ~/myprog/main.cpp return result; } #include "foo.hpp" void Foo::print(char *prefix) { int main() { cout << prefix << value_ << "n"; bar::Foo foo(2); } char * prefix = "the answer="; } for(int i=0; i<4; i++) { foo.calc(i); } foo.print(prefix); return 0; }
  • 16. 5. single argument constructors should usually be explicit ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: Foo(int seed); using namespace std; int calc(int number = 7); int getValue() { namespace bar { return value_; Foo::Foo(int seed) { } value_ = seed; void print(char* prefix); } private: int value_; int Foo::my_magic(int a, int b) { int my_magic(int a, int b); return a + b - 3 + 8 - 5; }; } } int Foo::calc(int number) { int result = my_magic(value_, number); value_ += result; ~/myprog/main.cpp return result; } #include "foo.hpp" void Foo::print(char *prefix) { int main() { cout << prefix << value_ << "n"; bar::Foo foo(2); } char * prefix = "the answer="; } for(int i=0; i<4; i++) { foo.calc(i); } foo.print(prefix); return 0; }
  • 17. 5. single argument constructors should usually be explicit ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); using namespace std; int calc(int number = 7); int getValue() { namespace bar { return value_; Foo::Foo(int seed) { } value_ = seed; void print(char* prefix); } private: int value_; int Foo::my_magic(int a, int b) { int my_magic(int a, int b); return a + b - 3 + 8 - 5; }; } } int Foo::calc(int number) { int result = my_magic(value_, number); value_ += result; ~/myprog/main.cpp return result; } #include "foo.hpp" void Foo::print(char *prefix) { int main() { cout << prefix << value_ << "n"; bar::Foo foo(2); } char * prefix = "the answer="; } for(int i=0; i<4; i++) { foo.calc(i); } foo.print(prefix); return 0; }
  • 18. 6. initialize the state of the object properly ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); using namespace std; int calc(int number = 7); int getValue() { namespace bar { return value_; Foo::Foo(int seed) { } value_ = seed; void print(char* prefix); } private: int value_; int Foo::my_magic(int a, int b) { int my_magic(int a, int b); return a + b - 3 + 8 - 5; }; } } int Foo::calc(int number) { int result = my_magic(value_, number); value_ += result; ~/myprog/main.cpp return result; } #include "foo.hpp" void Foo::print(char *prefix) { int main() { cout << prefix << value_ << "n"; bar::Foo foo(2); } char * prefix = "the answer="; } for(int i=0; i<4; i++) { foo.calc(i); } foo.print(prefix); return 0; }
  • 19. 6. initialize the state of the object properly ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); using namespace std; int calc(int number = 7); int getValue() { namespace bar { return value_; Foo::Foo(int seed) : value_(seed) { } } void print(char* prefix); private: int Foo::my_magic(int a, int b) { int value_; return a + b - 3 + 8 - 5; int my_magic(int a, int b); } }; } int Foo::calc(int number) { int result = my_magic(value_, number); value_ += result; return result; ~/myprog/main.cpp } #include "foo.hpp" void Foo::print(char *prefix) { cout << prefix << value_ << "n"; int main() { } bar::Foo foo(2); } char * prefix = "the answer="; for(int i=0; i<4; i++) { foo.calc(i); } foo.print(prefix); return 0; }
  • 20. 7. use a consistent naming convention, camelCase or under_score ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); using namespace std; int calc(int number = 7); int getValue() { namespace bar { return value_; Foo::Foo(int seed) : value_(seed) { } } void print(char* prefix); private: int Foo::my_magic(int a, int b) { int value_; return a + b - 3 + 8 - 5; int my_magic(int a, int b); } }; } int Foo::calc(int number) { int result = my_magic(value_, number); value_ += result; return result; ~/myprog/main.cpp } #include "foo.hpp" void Foo::print(char *prefix) { cout << prefix << value_ << "n"; int main() { } bar::Foo foo(2); } char * prefix = "the answer="; for(int i=0; i<4; i++) { foo.calc(i); } foo.print(prefix); return 0; }
  • 21. 7. use a consistent naming convention, camelCase or under_score ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); using namespace std; int calc(int number = 7); int getValue() { namespace bar { return value_; Foo::Foo(int seed) : value_(seed) { } } void print(char* prefix); private: int Foo::myMagic(int a, int b) { int value_; return a + b - 3 + 8 - 5; int myMagic(int a, int b); } }; } int Foo::calc(int number) { int result = myMagic(value_, number); value_ += result; return result; ~/myprog/main.cpp } #include "foo.hpp" void Foo::print(char *prefix) { cout << prefix << value_ << "n"; int main() { } bar::Foo foo(2); } char * prefix = "the answer="; for(int i=0; i<4; i++) { foo.calc(i); } foo.print(prefix); return 0; }
  • 22. 8. do not prefix queries and modifiers with get/set ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); using namespace std; int calc(int number = 7); int getValue() { namespace bar { return value_; Foo::Foo(int seed) : value_(seed) { } } void print(char* prefix); private: int Foo::myMagic(int a, int b) { int value_; return a + b - 3 + 8 - 5; int myMagic(int a, int b); } }; } int Foo::calc(int number) { int result = myMagic(value_, number); value_ += result; return result; ~/myprog/main.cpp } #include "foo.hpp" void Foo::print(char *prefix) { cout << prefix << value_ << "n"; int main() { } bar::Foo foo(2); } char * prefix = "the answer="; for(int i=0; i<4; i++) { foo.calc(i); } foo.print(prefix); return 0; }
  • 23. 8. do not prefix queries and modifiers with get/set ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); using namespace std; int calc(int number = 7); int value() { namespace bar { return value_; Foo::Foo(int seed) : value_(seed) { } } void print(char* prefix); private: int Foo::myMagic(int a, int b) { int value_; return a + b - 3 + 8 - 5; int myMagic(int a, int b); } }; } int Foo::calc(int number) { int result = myMagic(value_, number); value_ += result; return result; ~/myprog/main.cpp } #include "foo.hpp" void Foo::print(char *prefix) { cout << prefix << value_ << "n"; int main() { } bar::Foo foo(2); } char * prefix = "the answer="; for(int i=0; i<4; i++) { foo.calc(i); } foo.print(prefix); return 0; }
  • 24. 9. do not import namespaces ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); using namespace std; int calc(int number = 7); int value() { namespace bar { return value_; Foo::Foo(int seed) : value_(seed) { } } void print(char* prefix); private: int Foo::myMagic(int a, int b) { int value_; return a + b - 3 + 8 - 5; int myMagic(int a, int b); } }; } int Foo::calc(int number) { int result = myMagic(value_, number); value_ += result; return result; ~/myprog/main.cpp } #include "foo.hpp" void Foo::print(char *prefix) { cout << prefix << value_ << "n"; int main() { } bar::Foo foo(2); } char * prefix = "the answer="; for(int i=0; i<4; i++) { foo.calc(i); } foo.print(prefix); return 0; }
  • 25. 9. do not import namespaces ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); namespace bar { int calc(int number = 7); Foo::Foo(int seed) : value_(seed) { int value() { } return value_; } int Foo::myMagic(int a, int b) { void print(char* prefix); return a + b - 3 + 8 - 5; private: } int value_; int myMagic(int a, int b); int Foo::calc(int number) { }; int result = myMagic(value_, number); } value_ += result; return result; } ~/myprog/main.cpp void Foo::print(char *prefix) { std::cout << prefix << value_ << "n"; #include "foo.hpp" } } int main() { bar::Foo foo(2); char * prefix = "the answer="; for(int i=0; i<4; i++) { foo.calc(i); } foo.print(prefix); return 0; }
  • 26. 10. query functions should be declared const ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); namespace bar { int calc(int number = 7); Foo::Foo(int seed) : value_(seed) { int value() { } return value_; } int Foo::myMagic(int a, int b) { void print(char* prefix); return a + b - 3 + 8 - 5; private: } int value_; int myMagic(int a, int b); int Foo::calc(int number) { }; int result = myMagic(value_, number); } value_ += result; return result; } ~/myprog/main.cpp void Foo::print(char *prefix) { std::cout << prefix << value_ << "n"; #include "foo.hpp" } } int main() { bar::Foo foo(2); char * prefix = "the answer="; for(int i=0; i<4; i++) { foo.calc(i); } foo.print(prefix); return 0; }
  • 27. 10. query functions should be declared const ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); namespace bar { int calc(int number = 7); Foo::Foo(int seed) : value_(seed) { int value() const { } return value_; } int Foo::myMagic(int a, int b) { void print(char* prefix) const; return a + b - 3 + 8 - 5; private: } int value_; int myMagic(int a, int b); int Foo::calc(int number) { }; int result = myMagic(value_, number); } value_ += result; return result; } ~/myprog/main.cpp void Foo::print(char *prefix) const { std::cout << prefix << value_ << "n"; #include "foo.hpp" } } int main() { bar::Foo foo(2); char * prefix = "the answer="; for(int i=0; i<4; i++) { foo.calc(i); } foo.print(prefix); return 0; }
  • 28. 11. non-const functions are modifiers ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); namespace bar { int calc(int number = 7); Foo::Foo(int seed) : value_(seed) { int value() const { } ? return value_; } int Foo::myMagic(int a, int b) { void print(char* prefix) const; return a + b - 3 + 8 - 5; private: } int value_; int myMagic(int a, int b); int Foo::calc(int number) { }; int result = myMagic(value_, number); } value_ += result; return result; } ~/myprog/main.cpp void Foo::print(char *prefix) const { std::cout << prefix << value_ << "n"; #include "foo.hpp" } } int main() { bar::Foo foo(2); char * prefix = "the answer="; for(int i=0; i<4; i++) { foo.calc(i); } foo.print(prefix); return 0; }
  • 29. 12. prefer free-standing functions ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); namespace bar { int calc(int number = 7); Foo::Foo(int seed) : value_(seed) { int value() const { } return value_; } int Foo::myMagic(int a, int b) { void print(char* prefix) const; return a + b - 3 + 8 - 5; private: } int value_; int myMagic(int a, int b); int Foo::calc(int number) { }; int result = myMagic(value_, number); } value_ += result; return result; } ~/myprog/main.cpp void Foo::print(char *prefix) const { std::cout << prefix << value_ << "n"; #include "foo.hpp" } } int main() { bar::Foo foo(2); char * prefix = "the answer="; for(int i=0; i<4; i++) { foo.calc(i); } foo.print(prefix); return 0; }
  • 30. 12. prefer free-standing functions ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); namespace bar { int calc(int number = 7); Foo::Foo(int seed) : value_(seed) { int value() const { } return value_; } int Foo::myMagic(int a, int b) { void print(char* prefix) const; return a + b - 3 + 8 - 5; private: } int value_; int myMagic(int a, int b); int Foo::calc(int number) { }; int result = myMagic(value_, number); } value_ += result; return result; } ~/myprog/main.cpp void Foo::print(char *prefix) const { std::cout << prefix << value_ << "n"; #include "foo.hpp" } } int main() { bar::Foo foo(2); char * prefix = "the answer="; for(int i=0; i<4; i++) { foo.calc(i); } foo.print(prefix); return 0; }
  • 31. 12. prefer free-standing functions ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); namespace bar { int calc(int number = 7); Foo::Foo(int seed) : value_(seed) { int value() const { } return value_; } int myMagic(int a, int b) { void print(char* prefix) const; return a + b - 3 + 8 - 5; private: } int value_; }; int Foo::calc(int number) { } int result = myMagic(value_, number); value_ += result; return result; } ~/myprog/main.cpp void Foo::print(char *prefix) const { std::cout << prefix << value_ << "n"; #include "foo.hpp" } } int main() { bar::Foo foo(2); char * prefix = "the answer="; for(int i=0; i<4; i++) { foo.calc(i); } foo.print(prefix); return 0; }
  • 32. 13. use anonymous namespaces for private free-standing functions ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); namespace bar { int calc(int number = 7); Foo::Foo(int seed) : value_(seed) { int value() const { } return value_; } int myMagic(int a, int b) { void print(char* prefix) const; return a + b - 3 + 8 - 5; private: } int value_; }; int Foo::calc(int number) { } int result = myMagic(value_, number); value_ += result; return result; } ~/myprog/main.cpp void Foo::print(char *prefix) const { std::cout << prefix << value_ << "n"; #include "foo.hpp" } } int main() { bar::Foo foo(2); char * prefix = "the answer="; for(int i=0; i<4; i++) { foo.calc(i); } foo.print(prefix); return 0; }
  • 33. 13. use anonymous namespaces for private free-standing functions ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); namespace { int calc(int number = 7); int myMagic(int a, int b) { int value() const { return a + b - 3 + 8 - 5; return value_; } } } void print(char* prefix) const; private: namespace bar { int value_; Foo::Foo(int seed) : value_(seed) { }; } } int Foo::calc(int number) { int result = myMagic(value_, number); value_ += result; return result; ~/myprog/main.cpp } #include "foo.hpp" void Foo::print(char *prefix) const { std::cout << prefix << value_ << "n"; int main() { } bar::Foo foo(2); } char * prefix = "the answer="; for(int i=0; i<4; i++) { foo.calc(i); } foo.print(prefix); return 0; }
  • 34. 14. do not inline stuff in the class definition ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); namespace { int calc(int number = 7); int myMagic(int a, int b) { int value() const { return a + b - 3 + 8 - 5; return value_; } } } void print(char* prefix) const; private: namespace bar { int value_; Foo::Foo(int seed) : value_(seed) { }; } } int Foo::calc(int number) { int result = myMagic(value_, number); value_ += result; return result; ~/myprog/main.cpp } #include "foo.hpp" void Foo::print(char *prefix) const { std::cout << prefix << value_ << "n"; int main() { } bar::Foo foo(2); } char * prefix = "the answer="; for(int i=0; i<4; i++) { foo.calc(i); } foo.print(prefix); return 0; }
  • 35. 14. do not inline stuff in the class definition ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); namespace { int calc(int number = 7); int myMagic(int a, int b) { int value() const; return a + b - 3 + 8 - 5; void print(char* prefix) const; } private: } int value_; }; namespace bar { Foo::Foo(int seed) : value_(seed) { inline int Foo::value() const { } return value_; } int Foo::calc(int number) { } int result = myMagic(value_, number); value_ += result; return result; ~/myprog/main.cpp } #include "foo.hpp" void Foo::print(char *prefix) const { std::cout << prefix << value_ << "n"; int main() { } bar::Foo foo(2); } char * prefix = "the answer="; for(int i=0; i<4; i++) { foo.calc(i); } foo.print(prefix); return 0; }
  • 36. 15. by default keep your stuff in the implementation file ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); namespace { int calc(int number = 7); int myMagic(int a, int b) { int value() const; return a + b - 3 + 8 - 5; void print(char* prefix) const; } private: } int value_; }; namespace bar { Foo::Foo(int seed) : value_(seed) { inline int Foo::value() const { } return value_; } int Foo::calc(int number) { } int result = myMagic(value_, number); value_ += result; return result; ~/myprog/main.cpp } #include "foo.hpp" void Foo::print(char *prefix) const { std::cout << prefix << value_ << "n"; int main() { } bar::Foo foo(2); } char * prefix = "the answer="; for(int i=0; i<4; i++) { foo.calc(i); } foo.print(prefix); return 0; }
  • 37. 15. by default keep your stuff in the implementation file ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); namespace { int calc(int number = 7); int myMagic(int a, int b) { int value() const; return a + b - 3 + 8 - 5; void print(char* prefix) const; } private: } int value_; }; namespace bar { } Foo::Foo(int seed) : value_(seed) { } int Foo::calc(int number) { int result = myMagic(value_, number); value_ += result; return result; ~/myprog/main.cpp } #include "foo.hpp" int Foo::value() const { return value_; int main() { } bar::Foo foo(2); char * prefix = "the answer="; void Foo::print(char *prefix) const { for(int i=0; i<4; i++) { std::cout << prefix << value_ << "n"; foo.calc(i); } } } foo.print(prefix); return 0; }
  • 38. 16. avoid member functions that both modifies and queries ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); namespace { int calc(int number = 7); int myMagic(int a, int b) { int value() const; return a + b - 3 + 8 - 5; void print(char* prefix) const; } private: } int value_; }; namespace bar { } Foo::Foo(int seed) : value_(seed) { } int Foo::calc(int number) { int result = myMagic(value_, number); value_ += result; return result; ~/myprog/main.cpp } #include "foo.hpp" int Foo::value() const { return value_; int main() { } bar::Foo foo(2); char * prefix = "the answer="; void Foo::print(char *prefix) const { for(int i=0; i<4; i++) { std::cout << prefix << value_ << "n"; foo.calc(i); } } } foo.print(prefix); return 0; }
  • 39. 16. avoid member functions that both modifies and queries ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); namespace { void calc(int number = 7); int myMagic(int a, int b) { int value() const; return a + b - 3 + 8 - 5; void print(char* prefix) const; } private: } int value_; }; namespace bar { } Foo::Foo(int seed) : value_(seed) { } void Foo::calc(int number) { value_ += myMagic(value_, number); } ~/myprog/main.cpp int Foo::value() const { return value_; #include "foo.hpp" } int main() { void Foo::print(char *prefix) const { bar::Foo foo(2); std::cout << prefix << value_ << "n"; char * prefix = "the answer="; } for(int i=0; i<4; i++) { } foo.calc(i); } foo.print(prefix); return 0; }
  • 40. 17. default arguments are depreciated, use delegation if you must ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); namespace { void calc(int number = 7); int myMagic(int a, int b) { int value() const; return a + b - 3 + 8 - 5; void print(char* prefix) const; } private: } int value_; }; namespace bar { } Foo::Foo(int seed) : value_(seed) { } void Foo::calc(int number) { value_ += myMagic(value_, number); } ~/myprog/main.cpp int Foo::value() const { return value_; #include "foo.hpp" } int main() { void Foo::print(char *prefix) const { bar::Foo foo(2); std::cout << prefix << value_ << "n"; char * prefix = "the answer="; } for(int i=0; i<4; i++) { } foo.calc(i); } foo.print(prefix); return 0; }
  • 41. 17. default arguments are depreciated, use delegation if you must ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); namespace { void calc(int number); int myMagic(int a, int b) { int value() const; return a + b - 3 + 8 - 5; void print(char* prefix) const; } private: } int value_; }; namespace bar { } Foo::Foo(int seed) : value_(seed) { } void Foo::calc(int number) { value_ += myMagic(value_, number); } ~/myprog/main.cpp int Foo::value() const { return value_; #include "foo.hpp" } int main() { void Foo::print(char *prefix) const { bar::Foo foo(2); std::cout << prefix << value_ << "n"; char * prefix = "the answer="; } for(int i=0; i<4; i++) { } foo.calc(i); } foo.print(prefix); return 0; }
  • 42. 18. the K&R vs BS war is over, use an extra space around & and * ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); namespace { void calc(int number); int myMagic(int a, int b) { int value() const; return a + b - 3 + 8 - 5; void print(char* prefix) const; } private: } int value_; }; namespace bar { } Foo::Foo(int seed) : value_(seed) { } void Foo::calc(int number) { value_ += myMagic(value_, number); } ~/myprog/main.cpp int Foo::value() const { return value_; #include "foo.hpp" } int main() { void Foo::print(char *prefix) const { bar::Foo foo(2); std::cout << prefix << value_ << "n"; char * prefix = "the answer="; } for(int i=0; i<4; i++) { } foo.calc(i); } foo.print(prefix); return 0; }
  • 43. 18. the K&R vs BS war is over, use an extra space around & and * ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); namespace { void calc(int number); int myMagic(int a, int b) { int value() const; return a + b - 3 + 8 - 5; void print(char * prefix) const; } private: } int value_; }; namespace bar { } Foo::Foo(int seed) : value_(seed) { } void Foo::calc(int number) { value_ += myMagic(value_, number); } ~/myprog/main.cpp int Foo::value() const { return value_; #include "foo.hpp" } int main() { void Foo::print(char * prefix) const { bar::Foo foo(2); std::cout << prefix << value_ << "n"; char * prefix = "the answer="; } for(int i=0; i<4; i++) { } foo.calc(i); } foo.print(prefix); return 0; }
  • 44. 19. by not specifying const you say that something will change ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); namespace { void calc(int number); int myMagic(int a, int b) { int value() const; return a + b - 3 + 8 - 5; void print(char * prefix) const; } private: } int value_; }; namespace bar { } Foo::Foo(int seed) : value_(seed) { } void Foo::calc(int number) { value_ += myMagic(value_, number); } ~/myprog/main.cpp int Foo::value() const { return value_; #include "foo.hpp" } int main() { void Foo::print(char * prefix) const { bar::Foo foo(2); std::cout << prefix << value_ << "n"; char * prefix = "the answer="; } for(int i=0; i<4; i++) { } foo.calc(i); } foo.print(prefix); return 0; }
  • 45. 19. by not specifying const you say that something will change ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); namespace { void calc(int number); int myMagic(int a, int b) { int value() const; return a + b - 3 + 8 - 5; void print(const char * prefix) const; } private: } int value_; }; namespace bar { } Foo::Foo(int seed) : value_(seed) { } void Foo::calc(int number) { value_ += myMagic(value_, number); } ~/myprog/main.cpp int Foo::value() const { return value_; #include "foo.hpp" } int main() { void Foo::print(const char * prefix) const { bar::Foo foo(2); std::cout << prefix << value_ << "n"; const char * prefix = "the answer="; } for(int i=0; i<4; i++) { } foo.calc(i); } foo.print(prefix); return 0; }
  • 46. 20. reduce scope of variables ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); namespace { void calc(int number); int myMagic(int a, int b) { int value() const; return a + b - 3 + 8 - 5; void print(const char * prefix) const; } private: } int value_; }; namespace bar { } Foo::Foo(int seed) : value_(seed) { } void Foo::calc(int number) { value_ += myMagic(value_, number); } ~/myprog/main.cpp int Foo::value() const { return value_; #include "foo.hpp" } int main() { void Foo::print(const char * prefix) const { bar::Foo foo(2); std::cout << prefix << value_ << "n"; const char * prefix = "the answer="; } for(int i=0; i<4; i++) { } foo.calc(i); } foo.print(prefix); return 0; }
  • 47. 20. reduce scope of variables ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); namespace { void calc(int number); int myMagic(int a, int b) { int value() const; return a + b - 3 + 8 - 5; void print(const char * prefix) const; } private: } int value_; }; namespace bar { } Foo::Foo(int seed) : value_(seed) { } void Foo::calc(int number) { value_ += myMagic(value_, number); } ~/myprog/main.cpp int Foo::value() const { return value_; #include "foo.hpp" } int main() { void Foo::print(const char * prefix) const { bar::Foo foo(2); std::cout << prefix << value_ << "n"; for(int i=0; i<4; i++) { } foo.calc(i); } } const char * prefix = "the answer="; foo.print(prefix); return 0; }
  • 48. 21. for-loops in C++ are often not written like this ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); namespace { void calc(int number); int myMagic(int a, int b) { int value() const; return a + b - 3 + 8 - 5; void print(const char * prefix) const; } private: } int value_; }; namespace bar { } Foo::Foo(int seed) : value_(seed) { } void Foo::calc(int number) { value_ += myMagic(value_, number); } ~/myprog/main.cpp int Foo::value() const { return value_; #include "foo.hpp" } int main() { void Foo::print(const char * prefix) const { bar::Foo foo(2); std::cout << prefix << value_ << "n"; for(int i=0; i<4; i++) { } foo.calc(i); } } const char * prefix = "the answer="; foo.print(prefix); return 0; }
  • 49. 21. for-loops in C++ are often not written like this ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); namespace { void calc(int number); int myMagic(int a, int b) { int value() const; return a + b - 3 + 8 - 5; void print(const char * prefix) const; } private: } int value_; }; namespace bar { } Foo::Foo(int seed) : value_(seed) { } void Foo::calc(int number) { value_ += myMagic(value_, number); } ~/myprog/main.cpp int Foo::value() const { return value_; #include "foo.hpp" } int main() { void Foo::print(const char * prefix) const { bar::Foo foo(2); std::cout << prefix << value_ << "n"; for (int i = 0; i != 4; ++i) { } foo.calc(i); } } const char * prefix = "the answer="; foo.print(prefix); return 0; }
  • 50. 22. in C++ you do not need to explicitly return from main ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); namespace { void calc(int number); int myMagic(int a, int b) { int value() const; return a + b - 3 + 8 - 5; void print(const char * prefix) const; } private: } int value_; }; namespace bar { } Foo::Foo(int seed) : value_(seed) { } void Foo::calc(int number) { value_ += myMagic(value_, number); } ~/myprog/main.cpp int Foo::value() const { return value_; #include "foo.hpp" } int main() { void Foo::print(const char * prefix) const { bar::Foo foo(2); std::cout << prefix << value_ << "n"; for (int i = 0; i != 4; ++i) { } foo.calc(i); } } const char * prefix = "the answer="; foo.print(prefix); return 0; }
  • 51. 22. in C++ you do not need to explicitly return from main ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); namespace { void calc(int number); int myMagic(int a, int b) { int value() const; return a + b - 3 + 8 - 5; void print(const char * prefix) const; } private: } int value_; }; namespace bar { } Foo::Foo(int seed) : value_(seed) { } void Foo::calc(int number) { value_ += myMagic(value_, number); } ~/myprog/main.cpp int Foo::value() const { return value_; #include "foo.hpp" } int main() { void Foo::print(const char * prefix) const { bar::Foo foo(2); std::cout << prefix << value_ << "n"; for (int i = 0; i != 4; ++i) { } foo.calc(i); } } const char * prefix = "the answer="; foo.print(prefix); return 0; }
  • 52. 22. in C++ you do not need to explicitly return from main ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); namespace { void calc(int number); int myMagic(int a, int b) { int value() const; return a + b - 3 + 8 - 5; void print(const char * prefix) const; } private: } int value_; }; namespace bar { } Foo::Foo(int seed) : value_(seed) { } void Foo::calc(int number) { value_ += myMagic(value_, number); } ~/myprog/main.cpp int Foo::value() const { return value_; #include "foo.hpp" } int main() { void Foo::print(const char * prefix) const { bar::Foo foo(2); std::cout << prefix << value_ << "n"; for (int i = 0; i != 4; ++i) { } foo.calc(i); } } const char * prefix = "the answer="; foo.print(prefix); }
  • 53. 23. inject side-effects if you must have them ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <iostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); namespace { void calc(int number); int myMagic(int a, int b) { int value() const; return a + b - 3 + 8 - 5; void print(const char * prefix) const; } private: } int value_; }; namespace bar { } Foo::Foo(int seed) : value_(seed) { } void Foo::calc(int number) { value_ += myMagic(value_, number); } ~/myprog/main.cpp int Foo::value() const { return value_; #include "foo.hpp" } int main() { void Foo::print(const char * prefix) const { bar::Foo foo(2); std::cout << prefix << value_ << "n"; for (int i = 0; i != 4; ++i) { } foo.calc(i); } } const char * prefix = "the answer="; foo.print(prefix); }
  • 54. 23. inject side-effects if you must have them ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <ostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); namespace { void calc(int number); int myMagic(int a, int b) { int value() const; return a + b - 3 + 8 - 5; void print(std::ostream & out, } const char * prefix) const; } private: int value_; namespace bar { }; Foo::Foo(int seed) : value_(seed) { } } void Foo::calc(int number) { value_ += myMagic(value_, number); } ~/myprog/main.cpp int Foo::value() const { return value_; #include <iostream> } #include "foo.hpp" void Foo::print(std::ostream & out, int main() { const char * prefix) const { bar::Foo foo(2); out << prefix << value_ << "n"; for (int i = 0; i != 4; ++i) { } foo.calc(i); } } const char * prefix = "the answer="; foo.print(std::cout, prefix); }
  • 55. 24. make sure headers compile by itself ~/myprog/foo.hpp ~/myprog/foo.cpp namespace bar { #include <ostream> class Foo { #include "foo.hpp" public: explicit Foo(int seed); namespace { void calc(int number); int myMagic(int a, int b) { int value() const; return a + b - 3 + 8 - 5; void print(std::ostream & out, } const char * prefix) const; } private: int value_; namespace bar { }; Foo::Foo(int seed) : value_(seed) { } } void Foo::calc(int number) { value_ += myMagic(value_, number); } ~/myprog/main.cpp int Foo::value() const { return value_; #include <iostream> } #include "foo.hpp" void Foo::print(std::ostream & out, int main() { const char * prefix) const { bar::Foo foo(2); out << prefix << value_ << "n"; for (int i = 0; i != 4; ++i) { } foo.calc(i); } } const char * prefix = "the answer="; foo.print(std::cout, prefix); }
  • 56. 24. make sure headers compile by itself ~/myprog/foo.hpp ~/myprog/foo.cpp #include <iostream> #include <ostream> #include "foo.hpp" namespace bar { class Foo { namespace { public: int myMagic(int a, int b) { explicit Foo(int seed); return a + b - 3 + 8 - 5; void calc(int number); } int value() const; } void print(std::ostream & out, const char * prefix) const; namespace bar { private: Foo::Foo(int seed) : value_(seed) { int value_; } }; } void Foo::calc(int number) { value_ += myMagic(value_, number); } ~/myprog/main.cpp int Foo::value() const { return value_; #include <iostream> } #include "foo.hpp" void Foo::print(std::ostream & out, int main() { const char * prefix) const { bar::Foo foo(2); out << prefix << value_ << "n"; for (int i = 0; i != 4; ++i) { } foo.calc(i); } } const char * prefix = "the answer="; foo.print(std::cout, prefix); }
  • 57. 25. include your own header file first, standard libraries last ~/myprog/foo.hpp ~/myprog/foo.cpp #include <iostream> #include <ostream> #include "foo.hpp" namespace bar { class Foo { namespace { public: int myMagic(int a, int b) { explicit Foo(int seed); return a + b - 3 + 8 - 5; void calc(int number); } int value() const; } void print(std::ostream & out, const char * prefix) const; namespace bar { private: Foo::Foo(int seed) : value_(seed) { int value_; } }; } void Foo::calc(int number) { value_ += myMagic(value_, number); } ~/myprog/main.cpp int Foo::value() const { return value_; #include <iostream> } #include "foo.hpp" void Foo::print(std::ostream & out, int main() { const char * prefix) const { bar::Foo foo(2); out << prefix << value_ << "n"; for (int i = 0; i != 4; ++i) { } foo.calc(i); } } const char * prefix = "the answer="; foo.print(std::cout, prefix); }
  • 58. 25. include your own header file first, standard libraries last ~/myprog/foo.hpp ~/myprog/foo.cpp #include <iostream> #include "foo.hpp" #include <ostream> namespace bar { class Foo { namespace { public: int myMagic(int a, int b) { explicit Foo(int seed); return a + b - 3 + 8 - 5; void calc(int number); } int value() const; } void print(std::ostream & out, const char * prefix) const; namespace bar { private: Foo::Foo(int seed) : value_(seed) { int value_; } }; } void Foo::calc(int number) { value_ += myMagic(value_, number); } ~/myprog/main.cpp int Foo::value() const { return value_; #include "foo.hpp" } #include <iostream> void Foo::print(std::ostream & out, int main() { const char * prefix) const { bar::Foo foo(2); out << prefix << value_ << "n"; for (int i = 0; i != 4; ++i) { } foo.calc(i); } } const char * prefix = "the answer="; foo.print(std::cout, prefix); }
  • 59. 26. prefer forward declarations in header files ~/myprog/foo.hpp ~/myprog/foo.cpp #include <iostream> #include "foo.hpp" #include <ostream> namespace bar { class Foo { namespace { public: int myMagic(int a, int b) { explicit Foo(int seed); return a + b - 3 + 8 - 5; void calc(int number); } int value() const; } void print(std::ostream & out, const char * prefix) const; namespace bar { private: Foo::Foo(int seed) : value_(seed) { int value_; } }; } void Foo::calc(int number) { value_ += myMagic(value_, number); } ~/myprog/main.cpp int Foo::value() const { return value_; #include "foo.hpp" } #include <iostream> void Foo::print(std::ostream & out, int main() { const char * prefix) const { bar::Foo foo(2); out << prefix << value_ << "n"; for (int i = 0; i != 4; ++i) { } foo.calc(i); } } const char * prefix = "the answer="; foo.print(std::cout, prefix); }
  • 60. 26. prefer forward declarations in header files ~/myprog/foo.hpp ~/myprog/foo.cpp #include <iosfwd> #include "foo.hpp" #include <ostream> namespace bar { class Foo { namespace { public: int myMagic(int a, int b) { explicit Foo(int seed); return a + b - 3 + 8 - 5; void calc(int number); } int value() const; } void print(std::ostream & out, const char * prefix) const; namespace bar { private: Foo::Foo(int seed) : value_(seed) { int value_; } }; } void Foo::calc(int number) { value_ += myMagic(value_, number); } ~/myprog/main.cpp int Foo::value() const { return value_; #include "foo.hpp" } #include <iostream> void Foo::print(std::ostream & out, int main() { const char * prefix) const { bar::Foo foo(2); out << prefix << value_ << "n"; for (int i = 0; i != 4; ++i) { } foo.calc(i); } } const char * prefix = "the answer="; foo.print(std::cout, prefix); }
  • 61. 27. don't need braces here ~/myprog/foo.hpp ~/myprog/foo.cpp #include <iosfwd> #include "foo.hpp" #include <ostream> namespace bar { class Foo { namespace { public: int myMagic(int a, int b) { explicit Foo(int seed); return a + b - 3 + 8 - 5; void calc(int number); } int value() const; } void print(std::ostream & out, const char * prefix) const; namespace bar { private: Foo::Foo(int seed) : value_(seed) { int value_; } }; } void Foo::calc(int number) { value_ += myMagic(value_, number); } ~/myprog/main.cpp int Foo::value() const { return value_; #include "foo.hpp" } #include <iostream> void Foo::print(std::ostream & out, int main() { const char * prefix) const { bar::Foo foo(2); out << prefix << value_ << "n"; for (int i = 0; i != 4; ++i) { } foo.calc(i); } } const char * prefix = "the answer="; foo.print(std::cout, prefix); }
  • 62. 27. don't need braces here ~/myprog/foo.hpp ~/myprog/foo.cpp #include <iosfwd> #include "foo.hpp" #include <ostream> namespace bar { class Foo { namespace { public: int myMagic(int a, int b) { explicit Foo(int seed); return a + b - 3 + 8 - 5; void calc(int number); } int value() const; } void print(std::ostream & out, const char * prefix) const; namespace bar { private: Foo::Foo(int seed) : value_(seed) { int value_; } }; } void Foo::calc(int number) { value_ += myMagic(value_, number); } ~/myprog/main.cpp int Foo::value() const { return value_; #include "foo.hpp" } #include <iostream> void Foo::print(std::ostream & out, int main() { const char * prefix) const { bar::Foo foo(2); out << prefix << value_ << "n"; for (int i = 0; i != 4; ++i) } foo.calc(i); } const char * prefix = "the answer="; foo.print(std::cout, prefix); }
  • 63. 28. avoid side-effects if you can, prefer free-standing functions ~/myprog/foo.hpp ~/myprog/foo.cpp #include <iosfwd> #include "foo.hpp" #include <ostream> namespace bar { class Foo { namespace { public: int myMagic(int a, int b) { explicit Foo(int seed); return a + b - 3 + 8 - 5; void calc(int number); } int value() const; } void print(std::ostream & out, const char * prefix) const; namespace bar { private: Foo::Foo(int seed) : value_(seed) { int value_; } }; } void Foo::calc(int number) { value_ += myMagic(value_, number); } ~/myprog/main.cpp int Foo::value() const { return value_; #include "foo.hpp" } #include <iostream> void Foo::print(std::ostream & out, int main() { const char * prefix) const { bar::Foo foo(2); out << prefix << value_ << "n"; for (int i = 0; i != 4; ++i) } foo.calc(i); } const char * prefix = "the answer="; foo.print(std::cout, prefix); }
  • 64. 28. avoid side-effects if you can, prefer free-standing functions ~/myprog/foo.hpp ~/myprog/foo.cpp #include <iosfwd> #include "foo.hpp" #include <ostream> namespace bar { class Foo { namespace { public: int myMagic(int a, int b) { explicit Foo(int seed); return a + b - 3 + 8 - 5; void calc(int number); } int value() const; } private: int value_; namespace bar { }; Foo::Foo(int seed) : value_(seed) { void print(std::ostream & out, } const char * prefix, const Foo & foo); void Foo::calc(int number) { } value_ += myMagic(value_, number); } ~/myprog/main.cpp int Foo::value() const { return value_; #include "foo.hpp" } #include <iostream> void print(std::ostream & out, int main() { const char * prefix, bar::Foo foo(2); const Foo & foo) { for (int i = 0; i != 4; ++i) out << prefix << foo.value() << "n"; foo.calc(i); } const char * prefix = "the answer="; } print(std::cout, prefix, foo); }
  • 65. 29. do not open a namespace when implementing free-standing functions ~/myprog/foo.hpp ~/myprog/foo.cpp #include <iosfwd> #include "foo.hpp" #include <ostream> namespace bar { class Foo { namespace { public: int myMagic(int a, int b) { explicit Foo(int seed); return a + b - 3 + 8 - 5; void calc(int number); } int value() const; } private: int value_; namespace bar { }; Foo::Foo(int seed) : value_(seed) { void print(std::ostream & out, } const char * prefix, const Foo & foo); void Foo::calc(int number) { } value_ += myMagic(value_, number); } ~/myprog/main.cpp int Foo::value() const { return value_; #include "foo.hpp" } #include <iostream> void print(std::ostream & out, int main() { const char * prefix, bar::Foo foo(2); const Foo & foo) { for (int i = 0; i != 4; ++i) out << prefix << foo.value() << "n"; foo.calc(i); } const char * prefix = "the answer="; } print(std::cout, prefix, foo); }
  • 66. 29. do not open a namespace when implementing free-standing functions ~/myprog/foo.hpp ~/myprog/foo.cpp #include <iosfwd> #include "foo.hpp" #include <ostream> namespace bar { class Foo { namespace { public: int myMagic(int a, int b) { explicit Foo(int seed); return a + b - 3 + 8 - 5; void calc(int number); } int value() const; } private: int value_; namespace bar { }; Foo::Foo(int seed) : value_(seed) { void print(std::ostream & out, } const char * prefix, const Foo & foo); void Foo::calc(int number) { } value_ += myMagic(value_, number); } ~/myprog/main.cpp int Foo::value() const { return value_; #include "foo.hpp" } #include <iostream> } int main() { void bar::print(std::ostream & out, bar::Foo foo(2); const char * prefix, for (int i = 0; i != 4; ++i) const bar::Foo & foo) { foo.calc(i); out << prefix << foo.value() << "n"; const char * prefix = "the answer="; } print(std::cout, prefix, foo); }
  • 67. 30. operator overloading is sometimes a nice thing ~/myprog/foo.hpp ~/myprog/foo.cpp #include <iosfwd> #include "foo.hpp" #include <ostream> namespace bar { class Foo { namespace { public: int myMagic(int a, int b) { explicit Foo(int seed); return a + b - 3 + 8 - 5; void calc(int number); } int value() const; } private: int value_; namespace bar { }; Foo::Foo(int seed) : value_(seed) { void print(std::ostream & out, } const char * prefix, const Foo & foo); void Foo::calc(int number) { } value_ += myMagic(value_, number); } ~/myprog/main.cpp int Foo::value() const { return value_; #include "foo.hpp" } #include <iostream> } int main() { void bar::print(std::ostream & out, bar::Foo foo(2); const char * prefix, for (int i = 0; i != 4; ++i) const bar::Foo & foo) { foo.calc(i); out << prefix << foo.value() << "n"; const char * prefix = "the answer="; } print(std::cout, prefix, foo); }