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

C#や.NET Frameworkがやっていること
C#や.NET FrameworkがやっていることC#や.NET Frameworkがやっていること
C#や.NET Frameworkがやっていること信之 岩永
 
Advanced JavaScript
Advanced JavaScriptAdvanced JavaScript
Advanced JavaScriptNascenia IT
 
JavaScript Tutorial
JavaScript  TutorialJavaScript  Tutorial
JavaScript TutorialBui Kiet
 
Writing php extensions in golang
Writing php extensions in golangWriting php extensions in golang
Writing php extensions in golangdo_aki
 
FCGI, C++로 Restful 서버 개발
FCGI, C++로 Restful 서버 개발FCGI, C++로 Restful 서버 개발
FCGI, C++로 Restful 서버 개발현승 배
 
Whitebox testing of Spring Boot applications
Whitebox testing of Spring Boot applicationsWhitebox testing of Spring Boot applications
Whitebox testing of Spring Boot applicationsYura Nosenko
 
ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022Alexander Ioffe
 
자바에서 null을 안전하게 다루는 방법
자바에서 null을 안전하게 다루는 방법자바에서 null을 안전하게 다루는 방법
자바에서 null을 안전하게 다루는 방법Sungchul Park
 
The tests are trying to tell you something@VoxxedBucharest.pptx
The tests are trying to tell you something@VoxxedBucharest.pptxThe tests are trying to tell you something@VoxxedBucharest.pptx
The tests are trying to tell you something@VoxxedBucharest.pptxVictor Rentea
 
炎炎夏日學 Android 課程 - Part1: Kotlin 語法介紹
炎炎夏日學 Android 課程 -  Part1: Kotlin 語法介紹炎炎夏日學 Android 課程 -  Part1: Kotlin 語法介紹
炎炎夏日學 Android 課程 - Part1: Kotlin 語法介紹Johnny Sung
 
Introduction to Coroutines @ KotlinConf 2017
Introduction to Coroutines @ KotlinConf 2017Introduction to Coroutines @ KotlinConf 2017
Introduction to Coroutines @ KotlinConf 2017Roman Elizarov
 
Functional programming with Java 8
Functional programming with Java 8Functional programming with Java 8
Functional programming with Java 8LivePerson
 
Introduction to Object-Oriented Programming & Design Principles (TCF 2014)
Introduction to Object-Oriented Programming & Design Principles (TCF 2014)Introduction to Object-Oriented Programming & Design Principles (TCF 2014)
Introduction to Object-Oriented Programming & Design Principles (TCF 2014)Michael Redlich
 
初心者向けCTFのWeb分野の強化法
初心者向けCTFのWeb分野の強化法初心者向けCTFのWeb分野の強化法
初心者向けCTFのWeb分野の強化法kazkiti
 
Py.test
Py.testPy.test
Py.testsoasme
 
Standard Template Library
Standard Template LibraryStandard Template Library
Standard Template LibraryNilesh Dalvi
 

What's hot (20)

C#や.NET Frameworkがやっていること
C#や.NET FrameworkがやっていることC#や.NET Frameworkがやっていること
C#や.NET Frameworkがやっていること
 
Advanced JavaScript
Advanced JavaScriptAdvanced JavaScript
Advanced JavaScript
 
Project Lombok!
Project Lombok!Project Lombok!
Project Lombok!
 
Go入門
Go入門Go入門
Go入門
 
JavaScript Tutorial
JavaScript  TutorialJavaScript  Tutorial
JavaScript Tutorial
 
Writing php extensions in golang
Writing php extensions in golangWriting php extensions in golang
Writing php extensions in golang
 
FCGI, C++로 Restful 서버 개발
FCGI, C++로 Restful 서버 개발FCGI, C++로 Restful 서버 개발
FCGI, C++로 Restful 서버 개발
 
Whitebox testing of Spring Boot applications
Whitebox testing of Spring Boot applicationsWhitebox testing of Spring Boot applications
Whitebox testing of Spring Boot applications
 
ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022
 
자바에서 null을 안전하게 다루는 방법
자바에서 null을 안전하게 다루는 방법자바에서 null을 안전하게 다루는 방법
자바에서 null을 안전하게 다루는 방법
 
The tests are trying to tell you something@VoxxedBucharest.pptx
The tests are trying to tell you something@VoxxedBucharest.pptxThe tests are trying to tell you something@VoxxedBucharest.pptx
The tests are trying to tell you something@VoxxedBucharest.pptx
 
炎炎夏日學 Android 課程 - Part1: Kotlin 語法介紹
炎炎夏日學 Android 課程 -  Part1: Kotlin 語法介紹炎炎夏日學 Android 課程 -  Part1: Kotlin 語法介紹
炎炎夏日學 Android 課程 - Part1: Kotlin 語法介紹
 
Inheritance in java
Inheritance in javaInheritance in java
Inheritance in java
 
Introduction to Coroutines @ KotlinConf 2017
Introduction to Coroutines @ KotlinConf 2017Introduction to Coroutines @ KotlinConf 2017
Introduction to Coroutines @ KotlinConf 2017
 
Functional programming with Java 8
Functional programming with Java 8Functional programming with Java 8
Functional programming with Java 8
 
Introduction to Object-Oriented Programming & Design Principles (TCF 2014)
Introduction to Object-Oriented Programming & Design Principles (TCF 2014)Introduction to Object-Oriented Programming & Design Principles (TCF 2014)
Introduction to Object-Oriented Programming & Design Principles (TCF 2014)
 
初心者向けCTFのWeb分野の強化法
初心者向けCTFのWeb分野の強化法初心者向けCTFのWeb分野の強化法
初心者向けCTFのWeb分野の強化法
 
Py.test
Py.testPy.test
Py.test
 
Flask – Python
Flask – PythonFlask – Python
Flask – Python
 
Standard Template Library
Standard Template LibraryStandard Template Library
Standard Template Library
 

Viewers also liked

Viewers also liked (20)

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
 
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++
 

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

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
 
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
 
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
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
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
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
🐬 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
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
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
 
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
 
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
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
[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
 
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
 
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
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdflior mazor
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 

Recently uploaded (20)

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
 
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
 
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
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
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
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
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
 
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
 
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
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
[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
 
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
 
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
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 

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); }