Post on 02-Jan-2016
description
C++ Part IIC++ Part II
Elliott WolinElliott WolinSummer Student Lecture SeriesSummer Student Lecture Series
JLabJLab25-Jul-200825-Jul-2008
OutlineOutline
IntroductionIntroduction Safe ProgrammingSafe Programming Efficient ProgrammingEfficient Programming Topics Not CoveredTopics Not Covered SummarySummary
IntroductionIntroduction
C++ is huge, powerfulC++ is huge, powerful Many ways to do things incorrectlyMany ways to do things incorrectly Error/debugger support poorError/debugger support poor
incomprehensible compiler errorsincomprehensible compiler errors Program safely, efficiently from the startProgram safely, efficiently from the start
Develop good habits early and stick with themDevelop good habits early and stick with them Extra time up front pays off!Extra time up front pays off! Program lifecycle dominated by maintenance!Program lifecycle dominated by maintenance!
Programming Programming
““is-a” versus “has-a” relationshipis-a” versus “has-a” relationship don’t confuse themdon’t confuse them electron “is-a” lepton and “has-a” spinelectron “is-a” lepton and “has-a” spin
Design PatternsDesign Patterns attempt to catalog programming attempt to catalog programming
strategiesstrategies useful to some peopleuseful to some people http://en.wikipedia.org/wiki/Design_pattern_(compu
ter_science) see also see also http://en.wikipedia.org/wiki/Antipattern
Safe ProgrammingSafe Programming
Const correctnessConst correctness ExceptionsExceptions Safe castingSafe casting
Const CorrectnessConst Correctness Vastly improves reliabilityVastly improves reliability
// const for variables
T myT; // T is some type
T *tPtr; // pointer to T
const T *tPtr; // pointer to const T;
T *const tPtr = &myT; // const pointer to T;
const T *const tPtr = &myT; // const pointer to const T
Const CorrectnessConst Correctness
// compare the following two prototypes where the function should
// not change any of its arguments
// not safe and/or efficient
int myFunc(int i, int *iPtr, myObj o, myObj *oPtr);
// safer and more efficient
int myFunc(int i, const int *iPtr, const myObj &o, const myObj *oPtr);
class MyClass {
private: int val;
public: void myConstMethod(int x) const { cout << val << endl; … }
};
Const member functionsConst member functions Says that method does NOT change objectSays that method does NOT change object Allows method to be called via const Allows method to be called via const
pointer or referencepointer or reference
ExceptionsExceptions Distinguish normal from error returnDistinguish normal from error return Promotes much cleaner codePromotes much cleaner code
// C/Fortran style
int myFunc(int x, int *result);
int err, result1, result2;
err = myFunc(2,&result1);
if(err!=0) {…}
if(result1>7) {…}
err = myFunc(4,&result2);
if(err!=0) {…}
if(result2>8) {…}
…
// using exceptions
int myFunc(int x) throw(myException);
try {
if(myFunc(2)>7) {…}
if(myFunc(4)>8) {…}
…
} catch (myException &e) {
cerr << e.what() << endl;
}
if(…)throw(MyException(28)); // constructor invoked
// alternate syntax, a la Geant4 examples
int err;
…
if(…)throw(MyException(err=28));
How to throw an exceptionHow to throw an exception
#include <exception> // c++ default exception base class
class myException : public exception {
private:
int errCode; // the error code
public:
myException(int code) : errCode(code) {}
// override exception base class method what(void)
const char* what(void) const throw() {
return(“myException thrown, something bad happened!”);
}
};
Exception classException class
Throw specificationsThrow specifications
int myFunc(int); // may throw anything
int myFunc(int) throw(x); // may throw x // runtime error anything else thrown
int myFunc(int) throw(); // runtime error if anything thrown
Safe CastingSafe Casting
Do not use C-style casting!Do not use C-style casting! Old way just tricked the compilerOld way just tricked the compiler
// the old way, for those who possess great faith
int myFunc(void *x) {
MyObj *oPtr = (MyObj*)x;
oPtr->xVal=3; // what if x is NOT MyObj* ???
}
Safe CastingSafe Casting
The new, safer way uses:The new, safer way uses:
static_cast<>() // cast with minimal checkingstatic_cast<>() // cast with minimal checking dynamic_cast<>() // cast with run-time checkdynamic_cast<>() // cast with run-time check const_cast<>() // remove const-nessconst_cast<>() // remove const-ness reinterpret_cast<>() // don’t use this!reinterpret_cast<>() // don’t use this!
// the new way (templates explained later…)
int myFunc(void *x) {
MyObj *oPtr = dynamic_cast<MyObj*>(x);
if(oPtr!=NULL) {…} // run-time check
float f;
int i = static_cast<int>(f); // also acceptable
}
// dynamic_cast commonly used in this type of situation:
// assume Derived inherits from Base
Base *b = new Derived();
…
Derived *d = dynamic_cast<Derived*>(b);
if(d!=NULL) {…}
Efficient ProgrammingEfficient Programming
Variable scope and namespaces Variable scope and namespaces Strings and streamsStrings and streams Operator overloadingOperator overloading TemplatesTemplates Standard Template Library (STL)Standard Template Library (STL)
Variable ScopeVariable Scope
int myFunc() {
int x = 1;
if(…) {
int y = 2; // y only exists in the if clause, between the braces
…
int x = 3; // creates a new variable, hides original!
…
}
y = 10; // ERROR: y is not defined here!
}
Variables usually exist between Variables usually exist between { and }{ and } Variable definition may hide another Variable definition may hide another oneone
NamespacesNamespaces Avoid name clashesAvoid name clashes All packages should be in their own namespaceAll packages should be in their own namespace
namespace fred {
int x;
float y;
…
}
fred::x = 2;
or:
using namespace fred;
x = 2;
StringsStrings No more C-style char* needed!No more C-style char* needed! Use full-featured ANSI string classUse full-featured ANSI string class
#include <string>
using namespace std; // otherwise must type std::string
string s;
s = “hello”;
s += “ world”; // can add to strings
if(s==“goodbye world”) {…} // case-sensitive string comparison
if(s.length()>10) {…} // string length
oldFunc(s.c_str()); // can get C-style char* if needed
StreamsStreams I/O, string streams, other streamsI/O, string streams, other streams
#include <iostream>
#include <iomanip>
using namespace std; // or else need std::cout, etc.
cout << “Hello World” << endl; // prints to screen
#include <sstream>
stringstream ss;
int x = 123456;
ss << “x in hex is: 0x“ << hex << x << ends;
cout << ss.str() << endl; // convert to string and print
// use of stream paradigm
myContainer << anObject << anotherObject;
Operator OverloadingOperator Overloading
Can redefine the meaning of + - * / etc.Can redefine the meaning of + - * / etc.
MyVector v1, v2, v3;
MyMatrix m1;
v3 = v1 + v2; // operator + defined for myVector
v2 = m1 * v1; // operator * defined between matrix and vector
m1++; // operator ++ defined for matrix
v3 = 10 * v3; // operator * defined for integer and vector
MyVector operator+ (const MyVector &vLeft, const MyVector &vRight) {
// should do some error checking here…
int len = vLeft.length();
MyVector vSum(len);
for(int i = 0; i<len; i++) { vSum[i] = vLeft[i] + vRight[i]; }
return(vSum);
}
Can redefine almost all C++ operatorsCan redefine almost all C++ operators () [] ^ % ! | & << >> and many others() [] ^ % ! | & << >> and many others
Useful, but easy to abuseUseful, but easy to abuse e.g. do NOT redefine + in non-intuitive way!e.g. do NOT redefine + in non-intuitive way! cannot redefine operators between built-in cannot redefine operators between built-in
typestypes
TemplatesTemplates Generic programming, independent of typeGeneric programming, independent of type This is a very big subject!This is a very big subject! Not compiled unless used (instantiated)Not compiled unless used (instantiated)
template <typename T> class MyTemplClass {
T myT; // variable of type T
static T min(T t1, T t2) { // method takes 2 T’s, returns T
return((t1<t2)?t1:t2);
}
};
// usage
MyTemplClass<MyVector> v; // MyVector flavor of MyTemplClass
MyTemplClass<int> i; // int flavor of MyTemplClass
Standard Template LibraryStandard Template Library
Large library of utilities, including:Large library of utilities, including:
ContainersContainers vector, list, map, queue, etc.vector, list, map, queue, etc.
IteratorsIterators Iterate over objects in containersIterate over objects in containers
AlgorithmsAlgorithms Do something to objects in containers (sort, etc.)Do something to objects in containers (sort, etc.) Generally very efficientGenerally very efficient
Also, function objects, function object adaptors, Also, function objects, function object adaptors, utilities, etc.utilities, etc.
#include <vector>
using namespace std;
vector<int> iVector(10);
vector<float> fVector;
for(int i=0; i<10; i++) {
iVector[i]=i;
fVector.push_back(i*1.234);
}
ContainersContainers
#include <list>
using namespace std;
list<int> l;
for(int i=0; i<10; i++) l.push_back(i);
// iterate over list contents
list<int>::iterator iter;
for(iter=l.begin(); iter!=l.end(); iter++) {
cout << *iter << endl; // *iter is current element in the list
}
IteratorsIterators
#include <vector>
#include <algorithm>
using namespace std;
// create vector of 100 random integers < 1000
vector<int> vec;
for(int i=0; i<100; i++) vec.push_back(ran(1000));
// sort using STL algorithm
sort(vec.begin(), vec.end());
AlgorithmsAlgorithms
Topics Not CoveredTopics Not Covered Multi-threadingMulti-threading
multiple, simultaneous execution threadsmultiple, simultaneous execution threads concurrency problems, need locking mechanismconcurrency problems, need locking mechanism
Smart pointersSmart pointers avoid memory leaks, no need to call “delete”avoid memory leaks, no need to call “delete”
RTTIRTTI run-time type informationrun-time type information
Doxygen documentation facilityDoxygen documentation facility documentation derived from special comments in your documentation derived from special comments in your
codecode Member function pointersMember function pointers
can point to an member function of an objectcan point to an member function of an object
BOOST LibraryBOOST Library
Well-supported library containing many useful Well-supported library containing many useful facilitiesfacilities smart pointerssmart pointers object serializationobject serialization thread and multi-processing librarythread and multi-processing library tuplestuples new types of containersnew types of containers and much more!and much more!
Available on all major platformsAvailable on all major platforms Widely usedWidely used
Use BOOST, but choose wisely!Use BOOST, but choose wisely!
SummarySummary
C++ is a big, complicated languageC++ is a big, complicated language ““Use the good features of a language, Use the good features of a language,
avoid the bad ones”, avoid the bad ones”, The Elements of The Elements of Programming StyleProgramming Style, Kernighan and , Kernighan and Plauger, 1978Plauger, 1978
Be familiar with C++ features, learn and Be familiar with C++ features, learn and use the good onesuse the good ones
Practice safe programmingPractice safe programming const correctness, exceptions, safe casting, etc.const correctness, exceptions, safe casting, etc.
Practice efficient programmingPractice efficient programming use strings, templates, the STL, BOOST, etc.use strings, templates, the STL, BOOST, etc.