Beruflich Dokumente
Kultur Dokumente
Shem Chandran
Structures
Collections of data records Role expanded in C++; like a class except for the default access A struct is defined by: struct myStructType /*: inheritances */ { // public members protected: // protected members private: // private members } myStructName; //optional list of variables object of type myStructType myStructType obj1;
Structures
// struct definition: struct Point { double x, y; }; // create variables int main() { Point blank; blank.x = 3.0; blank.y = 4.0; int x = blank.x; } // assignment operator Point blank = { 3.0, 4.0 }; Point blank; blank = {3.0, 4.0} ;//WRONG Point p1 = { 3.0, 4.0 }; Point p2 = p1;
Structures
//Structures as return types Point findCenter (Rectangle& box) { double x = box.corner.x + box.width/2; double y = box.corner.y + box.height/2; Point result = {x, y}; return result; } int main() { Rectangle box = { {0.0, 0.0}, 100, 200 }; Point center = findCenter (box); printPoint (center); Return 0; } Rectangle (Point corner, int width, int height);
Unions
Similar to structs the fields of a union share the same memory location multiple ways of viewing the same; No inheritance union item { // The item is 16-bits short theitem; struct { char lo; char hi; } portions; //struct type has no name // in little-endian lo accesses low 8-bits, hi upper 8-bits }; int main() { item myitem; myitem.theItem = 0xBEAD; myitem.portions.lo = 0xEF; // The item is now 0xBEEF return 0; }
Classes
Classes are user defined types have both data and functions members - encapsulation An instance of a class is called an object Class is a logical abstraction, objects exist in memory class myClass { data /* variables, constants */ functions access-specifier /* public, protected and private */ data functions /* section access-specifier, data, functions can be repeated */ } object-list; /* optional object list */ Data and functions are known as members of the class An object of class is declared by: myClass Ob;
Classes
Access-specifier private (default specifier) only members of the class and friends can access protected like private, but can be accessed also by derived classes private allows the members to be accessed by other parts of the program Member variables (also known as instance variables) Non-static members cannot be initialized in the class No member can be declared as auto, extern or register Member variables are usually private for encapsulation; made public if heavily used for faster runtime
Classes
class employee { char name[80]; double wage; public: void putname(char *n); void getname(char *n); void putwage(double w); double getwage(); }; void employee:: p putname(char *n) { strcpy(name, n); } void employee::getname(char *n) { strcpy(n, name); } void employee::putwage(double w) { wage = w; } double employee::getwage() { return wage; }
Classes
i int main() { employee ted; char name[80]; ted.putname("Ted Jones"); ted.putwage(75000); ted.getname(name); cout << name << " makes $"; cout << ted.getwage() << " per year. << endl; return 0; }
Friend Functions
A non-member function can be granted access to the private & protected members of a class by defining as a friend function. The prototype of the friend function must be declared in the class preceded by friend A function can be friend of >1 class, and be member of another class /* sum() is not a member class myclass { function of any class */ int a, b; i int sum(myclass x) public: { void set_ab(int i, int j); /* sum(), a friend of myclass, can directly friend int sum(myclass x); }; access a and b. */ void myclass::set_ab(int i, int j) { return x.a + x.b; a = i; } b = j; }
A class can be declared to be a friend class of another class The friend class & all its member functions have access to the private & protected members defined in the other class class TwoValues { int Min::min(TwoValues x) { int a; return x.a < x.b ? x.a : x.b; int b; } public: TwoValues(int i, int j) { int main() { a = i; b = j; } TwoValues ob(10, 20); friend class Min; Min m; }; cout << m.min(ob); class Min { return 0; public: } int min(TwoValues x); };
Friend Classes
Inline Functions
Short functions, not actually called but expanded in line at each invocation (like a function macro); request to compiler; its definition is preceded by inline keyword inline int max(int a, int b) { return a>b ? a : b; } int main() { cout << max(10,20); return 0; } Efficient code, reduce overheads in function call, return Short functions defined inside the class declaration including constructors/destructors are made inline automatically class myclass { int a, b; public: void init (int I, int j) { a=i; b=j } }
Special member functions (same name as class) called when new instances of a class are created Can define the data members upon object instantiation by passing parameters default constructor if none defined class myclass { int main() { int a, b; myclass ob(3, 5); public: ob.show(); myclass(int i, int j) {a=i; b=j;} return 0; } void show() {cout << a << " " << b; } //alternate way }; myclass ob = myclass (3, 4); //constructor with one parameter i int main() class X { { int a; X ob = 99; public: return 0; } X (int j) { a = j:} }
Constructors
Array Objects
Arrays of objects class cl int i; public: cl(int j) { i=j;} //constructor needs only 1 argument }; int main() { cl ob[3] = {1, 2, 3}; //short for {cl(1), cl(2), cl(3)}; cl a[5]; //error needs constructor with no parameter initializers //Adding another constructor in class declaration cl() {i=0;} //for non-initialized arrays cl b[5]; //not an error }
Pointers to Objects
To access class members using a pointer to an object use -> class cl { i int main() int i; { public: cl ob[3] = {1, 2, 3}; cl(int j) { i=j; } cl *p; int get_i() { return i; } int i; }; p = &ob.i; //addr of ob.i int main() { p = ob; // get start of array cl ob, *p; for(i=0; i<3; i++) { p = &ob; // get address of ob cout << p->get_i() << "\n"; cout << p->get_i(); //note -> p++; // point to next object return 0; } } return 0; }
this Pointer
When a member function is called, c++ adds a hidden pointer this to the invoking object class employee { double wage; public: void putwage(double w) { wage = w;} }; i int main() { employee ted; ted.putwage(75000); } The function call has only one parameter ted.putwage(75000); c++ internally converts it to p putwage(&ted, 75000) and converts the function to void putwage (employee* const this, double w) { this->wage = w; }
References
You can declare a reference that is simply address of a variable It must be initialized when created; the object pointed to cannot be changed later This independent reference is another name for the object
i int main() int b = 19; { ref = b; int a; cout << a << " "<< ref<<endl; int &ref = a; // independent ref ref--; // this decrements a // not affect what ref refers to a = 10; cout << a << " "<< ref<<endl; cout << a << " "<< ref <<endl; return 0; ref = 100; } cout << a << " "<< ref <<endl;
const objects
Declaration of objects as mutable or immutable Simple data type int const k = 7; or const int k = 7; value given at creation Pointers and references pointer to a const or const pointer int const *ptr or const int *ptr //pointee not modifiable int *constant ptr //pointer is constant, not reassignable int const *const ptr //both pointee & pointer are constant int const &num =7; //num can be set only at creation int &const num //error, const is redundant Objects const employee Ted; or employee const Ted;
Member functions if tagged const, cannot modify the object's data members int get() const { return j: } Const member functions can be called by const and nonconst objects, but non-const member functions cannot be invoked by const objects Often both const and non-const versions of functions w will be available (different implicit this parameter) Parameters to functions can also be made const void f(employee &Ted, const employee &Bob); const_cast, casts away the const nature of an object, making it modifiable for compatibility with an old library
const functions
Member pointers and references are shallow wrt to the const object, so while the member pointers cannot be modified, the pointees can be modified class S { int val; int *ptr; } void f(const S &s1) { int i = 42; s1.val = i; //error: s1 is const, so val is a const s1.ptr = &i; //error: s1 is const, so ptr is a const pointer *s1.ptr = i; //ok; data pointed to by ptr is mutable Volatile the value may not be modified by program, but may be changed by h/w; hence all references must be r read everytime (no temp storage or optimization)
const functions
Memory Allocation
3 Kinds of Program Data Static Data: Allocated at compiler time Dynamic Data: explicitly allocated and deallocated during program execution by C++ instructions written by programmer using operators new and delete Automatic Data: automatically created at function entry, resides in activation frame of the function, and is destroyed when returning from function
Memory Allocation
Dynamic Memory Allocation Static memory - where global and static variables live Heap memory dynamically allocated at execution time "managed" memory accessed using pointers Stack memory - used by automatic variables
Static Memory Global Variables Static Variables Heap Memory Free storage Dynamically allocated Stack Memory Auto variables Function parameters
In C, functions such as malloc () are used to dynamically allocate memory from the Heap. In C++, this is accomplished using the new and delete operators new is used to allocate memory during execution time returns a pointer to the address where the object is to be stored always returns a pointer to the type that follows the new
H s t a P
a t i c
p d a
r o g r a c o d e
- e
new DataType char* ptr; ptr = new char; {new allocates the requested object of type requested & returns a pointer to (address of ) the memory allocated} *ptr = B; { Note: The dynamic data has no variable name} cout << *ptr; The dynamically allocated object exists until the delete operator destroys it
The NULL Pointer There is a pointer constant called the null pointer d denoted by NULL (not memory address zero) It is an error to dereference a pointer whose value is N NULL (causes crash) while (ptr != NULL) { } Operator delete delete ptr or delete [ ] ptr {for arrays} The object or array currently pointed to by ptr is deallocated & the memory is returned to the free store ptr itself is not deallocated; its value is undefined; good to make it NULL
Reference Parameters
Two ways to pass parameters by reference: // c type pointers to arguments void neg(int *i) { *i = -*i; } int main() { int x; x = 10; cout << x << " negated is "; neg(&x); cout << x << "\n"; return 0; } //reference parameters void neg(int &i) { i = -i; // reference, not need * } int main() { int x; x = 10; cout << x << " negated is "; neg(x); // not need & cout << x << "\n"; return 0; }
When an object is passed by reference, a copy of the object is not made; hence constructor is not called When the function terminates, destructor is not called Faster, as stack operations saved class cl { int main() { int id; cl o(1); public: o.i = 10; int i; o.neg(o); cl::cl(int num) { cout << o.i << "\n"; cout << "Construct "<<num<<endl; return 0; id = num; } } cl::~cl() { cout << "Destroy " << id << endl; } Construct 1 void neg(cl &o) { o.i = -o.i; } //dot op -10 Destroy 1 };
Allocating Objects
When a class object is allocated dynamically by new, the object is created, calling a constructor and a pointer returned; when it is freed, its destructor is called class balance { r = new balance [2]; double cur_bal; //error - no parameterless constructor public: balance(double n) {cur_bal = n; } // provide since no default void set(double n) { cur_bal = n;} balance() {cur_bal = 0;} // in the class declaration } //then initialize int main() { r[0].set {12000.0}; balance *p, *q; r[1].set {11000.0}; p = new balance; delete p, q, r[]; p->set(12500.0); return 0; } q = new balance (15000.0);
Function Overloading
Same name for 2 or more functions Each definition should differ in the list of parameters (number and/or types). Just different return type will not suffice Sometimes, though they appear different, are the same void f(int *p); void f(int p[]); // error, *p is same as p[], both are pointers Constructers are often overloaded for flexible initialization class date { int day, month, year; public: date(); date(int m, int d, int y); date(char *d); //to allow 03/15/2010 or mar 15 2010
class loc { int n, int *d; } int main() { loc A; loc B(A);
A B 2 d 2 d
heap 5 7
Copy Constructor
C++ allows you to define a (deep) copy constructor, which will be used when one object is used to initialize another class array { int main() { int *p; array A(5); int size; int i; public: array(int sz) {size = sz; for (i=0; i<5; i++) A.put(i,i); p = new int[sz]; } //create array B initialized by A put (int i, int j) { p[i] = j; } array B(A); ~array() { delete [] p; } array::array(const array &a) { delete A, B; int i; return 0; } p = new int[sz]; for(i=0; i<a.size; i++) p[i] = a.p[i]; }
Operators can be overloaded to perform special operations relative to the classes; the original operator functions are retained relative to previous operands Operators are overloaded by creating operator functions as either member functions or friend functions // Overload + for loc class loc { loc loc::operator+(loc op2) { int long, lat; loc temp; public: temp.long = op2.long + long; loc() {} temp.lat = op2.lat + lat; loc(int lg, int lt) { return temp; } long = lg; lat = lt; } void show() { cout << long << Int main() { << lat << endl; } loc ob1(10,20), ob2(15,50); loc operator+(loc op2); ob1 = ob1 + ob2; }; ob1.show(); return 0; }
Operator Overloading
Operator loc +() has only one parameter though it overloads the binary + operator. The operand on the left side is implicitly passed through this The overloaded operator commonly returns an object of the class it operates on. It does not modify the operands // Overload asignment for loc // Overload prefix ++ for loc loc loc::operator=(loc op2) loc loc::operator++() { long = op2.long; { lat = op2.lat; long++; return *this; //return object lat++; generating the call return *this; } } loc ob1(1,2), ob2(3,4), ob3(5,6); ob1 = ob2 = ob3;
Operator Overloading
Operator Overloading
The postfix operator is defined as loc operator++(int x) //where x=0 The shorthand operators +=, -= can also be overloaded loc loc::operator+=(loc op2) { long += op2.long; lat += op2.lat; return *this; }
Inheritance
Allows creation of hierarchical classifications A Base Class (Parent or Super Class) is the class whose members are inherited by a Derived Class (Child or Class) class derivedclass-name : access-specifier baseclass-name The access-specifier is public, protected or private If not specified the access is by default private for classes and public for structs In all inheritance access cases, the private members of a base class not accessible from the derived classes Inheritance is a mechanism for building class types from existing class types, defining new class types to be A specialization An augmentation of existing types
Simple Inheritance
class point { protected: int x, y; public: point (int a, int b) { x=a; y=b; } void set(int a, int b) { x=a; y=b; } void show() { cout << x << " " << y << "\n"; } }; class point3d : public point { int z; public: point3d (int a, int b, int c) : point (a, b) { z=c; } void show() { cout << x << " " << y << " " << z << "\n"; } };
protected
public
Multiple Inheritance
class base1 { protected: int x; public: void showx() { cout << x << endl; } }; class base2 { protected: int y; public: void showy() { cout << y << endl; } }; class derived: public base1, public base2 { public: void set(int i, int j) { x=i; y=j; } }; int main() { derived ob; ob.set(10, 20); // derived constr ob.showx(); // from base1 ob.showy(); // from base2 return 0; } //assignment redo using only one routine called show in all 3 classes
Virtual Functions
A virtual function is a member function declared within a base class and redefined by a derived class The virtual function in the base class defines the form of the interface to that function. Each redefinition by a derived class creates a specific method related to that class Accessed normally virtual functions behave like other member functions When accessed via a pointer, they support run-time polymorphism (one interface, multiple methods) When a base pointer (or base-class reference) points to a derived object, c++ determines which version of the function to call, based on the type of object This determination is made at run-time
Virtual Functions class base { int main() { public: base *p, b; virtual void vfunc() { derived1 d1; cout << "This is base's vfunc()"; } derived2 d2; }; p = &b; // point to base class derived1 : public base { p->vfunc(); // base's vfunc() public: p = &d1; // point to derived1 void vfunc() { cout<<"This is derived1's vfunc(); } p->vfunc(); /* derived1's vfunc() */ }; p = &d2; // point to derived2 class derived2 : public base { p->vfunc(); /* derived2's public: vfunc() */ void vfunc() { cout<<"This is derived2's vfunc(); } return 0; } Note: }; d2.vfunc(); //calls derived2s Note: Virtual function not same as vfunc() overloaded function
Virtual Functions
When a virtual function is inherited, its virtual nature is also inherited A derived class that has inherited a virtual function is itself used as a base class for another derived class, which can again override the virtual function A derived class does not have to override a virtual function. In this case, when an object of this derived class accesses that function, the function defined by the base class is used Like inheritance, virtual functions are also hierarchical When a derived class fails to override a virtual function, the first redefinition found in reverse order of derivation is used C++ constructs a Virtual Function Table (VFT or Vtable) for each class that has a virtual function; each virtual function has entry to the most derived function in the inheritance hierarchy
An important use of abstract classes and virtual functions is in class libraries. You can create and control the interface of a general class, letting programmers adapt to their needs
Polymorphism
Key principle: one interface, multiple methods Compile-time polymorphism is achieved by overloading functions and operators Early binding (efficient) Run-time polymorphism is accomplished by inheritance and virtual functions Late binding When access is via a base pointer or reference, the virtual function actually called is determined by the type of object pointed to by the pointer In most cases this cannot be determined at compile time and the object and the function are not linked till run-time The main advantage of late-binding is flexibility, allowing you to create programs that can respond to events occurring as it executes Late binding can cause slower execution times
Complex objects are built from smaller simpler objects To facilitate building complex classes from simpler classes, c++ allows us to use classes as member variables in other classes #include CPU.h #include Mboard.h #include RAM.h Class PC { CPU m_cCPU Mboard m_cMboard RAM m_cRAM }; PC::PC(int nCPUspeed, char *sMbrdModel, int nRAMsize) : m_cCPU(nCPUspeed), m_cMboard(sMbrdModel), m_cRAM(nRAMsize) { }
Class Composition
Class Composition
class Mouth { public: void eat(Food bite); } //by inheritance ( is-a ) class Person : public Mouth{ }; //by composition ( has-a ) class Person { public: void eat(Food bite) { itsMouth.eat(bite): } private: Mouth itsMouth; }