30
C++ Part II C++ Part II Elliott Wolin Elliott Wolin Summer Student Lecture Series Summer Student Lecture Series JLab JLab 25-Jul-2008 25-Jul-2008

C++ Part II Elliott Wolin Summer Student Lecture Series JLab25-Jul-2008

Embed Size (px)

Citation preview

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.