350 likes | 360 Views
Learn C++ program structure, header files, CPP files, variables, class declarations, method definitions, pointer usage, and object copies in C++. Explore examples with concise explanations.
E N D
C++ program structure • C++ Program: collection of files • Header files • CPP source files • Files contain class, function, and global variable declarations/definitions • main() function serves as an entry point (just like in C)
Header Files (.h) • Contains class declarations • Prototypes for functions outside of classes • Others
Source Files (.cpp) • Function/method definitions • Directives (e.g., #include, #define) • Variables and initialization(global/static variables)
Variables in C++ • Regular variables • int x; x = 5; • bankaccount b; • Pointers • int *p; p = &x; • bankaccount *q; q = new bankaccount(); … delete q; • References/Aliases • int &r = x; // initialization required • Arrays • int num[20]; • int *a; a = new int[size]; • bankaccount *accts;accts = new bankaccount[10]; … delete[] accts;
Class declaration • class c{ private: members … public: members …}; • Members (fields and methods) grouped into public, private or protected regions • Fields can be regular variables, arrays, pointers, or references • Method declarations are (often) prototypes • Method defined separately from the class declaration
Example: class declaration class car { private: int dist; double gas; public: car(); void drive( int km ); void loadGas( double lit ); int getOdometerReading(); double getGasLeft(); };
Example: class declaration class car { private: int dist; double gas; public: car(); void drive( int km ); void loadGas( double lit ); int getOdometerReading(); double getGasLeft(); }; fields constructor methods
Example: method definitions car::car() { dist = 0; gas = 40.0; } void car::drive( int km ) { dist += km; gas -= km/10.0; } void car::loadGas( double lit ) { gas += lit; } int car::getOdometerReading() { return dist; } double car::getGasLeft() { return gas; }
Example: using objects int main() { car c; c.drive( 20 ); c.loadGas( 2 ); cout << "c: km-" << c.getOdometerReading() << " liters-" << c.getGasLeft() << endl; return 0; }
Role and necessity of header files • For a source file to compile correctly, the appropriate declarations need to precede the use of a class or function • Differentiate declaration from definition • Both the source file containing class definitions and the source file using the class must include the header file
Exercise: defining a C++ class Assemble the following C++ project: • banktester.cpp: using the bankaccount class and the power function • power.h: contains prototype for the power function • power.cpp: code for the power function • bankaccount.h: header file for the bankaccount class (needs to be revised) • bankaccount.cpp: source file for the bankaccount class (needs to be created) • Compare your output with correct output
C++ objects and copies bankaccount a(100); bankaccount b; bankaccount c = a; b = a;
a balance 100 C++ objects and copies bankaccount a(100); bankaccount b; bankaccount c = a; b = a;
a b balance balance 100 0 C++ objects and copies bankaccount a(100); bankaccount b; bankaccount c = a; b = a;
a b c balance balance balance 100 0 100 C++ objects and copies bankaccount a(100); bankaccount b; bankaccount c = a; b = a;
a b c balance balance balance 100 100 100 C++ objects and copies bankaccount a(100); bankaccount b; bankaccount c = a; b = a;
Pointers as fields • Suppose a class has fields that are pointers • Often because of dynamically allocated data • Introduces complexity when copying objects • In C++, the default is a shallow copy • Field values are copied verbatim • If fields are pointers, this is often not the desired intention • A deep copy requires additional coding
Example: integer vector class intvector { private: int size; int * data; public: intvector(); intvector(int s); // other methods... };
Example: integer vector intvector::intvector() { size = 5; data = new int[5]; } intvector::intvector(int s) { size = s; data = new int[s]; }
C++ objects and copies (pointers) intvector a; intvector b(10); intvector c = a; b = a;
a size data 5 C++ objects and copies (pointers) intvector a; intvector b(10); intvector c = a; b = a;
a b size size data data 5 10 C++ objects and copies (pointers) intvector a; intvector b(10); intvector c = a; b = a;
a b c size size size data data data 5 10 5 C++ objects and copies (pointers) intvector a; intvector b(10); intvector c = a; b = a;
a b c size size size data data data 5 5 5 C++ objects and copies (pointers) intvector a; intvector b(10); intvector c = a; b = a;
a b c size size size data data data 5 10 5 The intention intvector a; intvector b(10); intvector c = a; b = a; 5
b v balance size data 0 5 Variables going out of scope void method() { int i = 10; bankaccount b; intvector v; // ... } int main() { // before method(); // after return 0; } i 0
b v balance size data 0 5 Variables going out of scope void method() { int i = 10; bankaccount b; intvector v; // ... } int main() { // before method(); // after return 0; } i 0 ? Memory leak!
What needs to be programmed • Destructor • De-allocates previously allocated memory(need to call delete on pointers) • Signature: ~classname() • Copy constructor • Creates an object given an existing object • Need to allocate (construct) and then copy • Signature: classname( const classname& c ) • Assignment operator • Copies data from an existing object into an existing object • Need to de-allocate, allocate, then copy • Signature: classname& operator=( const classname& c )
intvector destructor intvector::~intvector() { delete [] data; } De-allocatesmemory allocated bydata = new int[size];
intvector copy constructor intvector::intvector(const intvector& c) { size = c.size; data = new int[size]; for(int i = 0; i < size; i++) data[i] = c.data[i]; } allocate then, copy
intvector assignment intvector& intvector::operator=(const intvector& c) { // TODO: to guard against self-assignment delete [] data; size = c.size; data = new int[size]; for(int i = 0; i < size; i++) data[i] = c.data[i]; return *this; } De-allocate existing data then, re-allocate finally, copy
Points to ponder • When is a copy constructor called? • someclass a = b; • someclass c(a); • When passing an object parameter duringmethod calls: somemethod(a); • Why do we need to guard against self-assignment? • What happens to this statement?: x = x; • Will a programmer ever perform self-assigmment? ( maybe: a[i] = a[j]; )
Lab • Write a dataset class with the following methods: • void addscore(double score): adds a score to the dataset • double computemean(): returns the average of the scores added so far(assume mean=0 if there are no scores in the dataset) • double computestdev(): returns the standard deviation: the squareroot of the average of squares of the difference of each element from the mean • A tester program (dstester.cpp) is provided • The dataset class should be dynamic • Make the array of scores “grow” in size as necessary
Lab, continued • Rules on dataset capacity • Begin with a capacity of size 10 • Whenever addscore is called on a full dataset, double the capacity • Make sure to implement a destructor, copy constructor and assignment operator • tester2() function tests whether you have programmed this correctly