Unit - 03 Structures, Classes and Objects Handling data and objects
Unit Introduction This unit covers structures, classes and objects
Unit Objectives After covering this unit you will understand… • Structures • Classes • Static data and member functions • Differences between structures and classes • References • Friend functions and classes
Structures • Following will be discussed in order to understand structures: • Declaration • Definition • Using structures • Nested structures
Declaring Structures • struct keyword is used for declaration • A structure is collection of variables and methods • In a structure, variables can have different data types • Can have private, protected and public access specifiers • The default access specifier is public • Semicolon “;” comes in the end to complete structure declaration
Example: Declaring Structures #include <iostream.h> struct SPart { private: int partType; // type of part, by default public public: float cost; // cost of part, be default public int GetPartType() { return partType; } }; // semicolon indicates end of declaration
Defining Structures • With declaration • A structure can be defined while declaring the structure • Structure Tag (which is used to name the structure) is not required, if a structure variable is defined while declaring the structure • Without declaration • Structures can be defined separately after declaration
Example: Defining Structures // declaring and defining together struct // tag is not required here { int partType; // type of part float cost; // cost of part } part; // declared and defined // declaring and defining separately struct SMachine // tag is required to define it separately { int machineType; // type of machine float cost; // cost of machine }; // declared only SMachine machine; // defined now
Using Structures • Structure can be initialised either by: • putting values in it; or • assigning other structure of same type • A structure variable can be assigned to other if they are instance of same structure • Assigning different structure types (even though they have exactly the same data types) is not allowed and will generate an error
Using Structures (contd.) • Structures are initialised using curly braces • Dot (.) operator is used to access the variables
Example: Using Structures // Initialising a structure variables # include <iostream.h> struct SPart { int partType; // type of part float cost; // cost of part }; void main() { SPart part1 = {12,23.56}; // Initializing variables SPart part2; part2 = part1; part2.cost = 13.5f; // cost variable accessed }
Structures • Nesting can be to any level (nth level) • Dot (.) operator is used to access the each inner level • When the inner most level is reached, the dot (.) operator will be used to access the variables and functions
Example: Nested Structures // Example of Structure nesting # include <iostream.h> struct SDistance { int feet; float inches; }; struct SRoom { SDistance length; SDistance width; };
Example: Nested Structures (contd.) void main() { SRoom dining = {{10,120},{10,120}} // Initializing SRoom study; study.length.feet = 10; // Assigning values study.length.inches = 120; study.width.feet = 10; study.width.inches = 120; }
Classes in C++ • Following will be discussed in order to understand Classes in C++: • Classes and objects • Access specifiers • Member functions • Constructors • Destructors • Static class data
Classes and Objects • Classes are the infrastructures while objects are runtime utilisation of those infrastructures • A class has functions and data • Member functions and data can be of type private, public or protected • Default access specifier is private • Variables cannot be initialised during declaration (as you can in Java)
Example: A Simple Class // demonstrates an object #include <iostream.h> class SmallObj // Specify a class name { private: int m_SomeData; // Class data public: void SetData(int data) // member function to set data { m_SomeData = data; } void ShowData() // member function to display data { cout << “\nData is “ << m_SomeData; } };
Example: A Simple Class (contd.) void main() { SmallObj s1, s2; // defining two objects s1.SetData(1234); // calling member function to set data s2.SetData(5677); s1.ShowData(); // calling member function to display // data s2.ShowData(); }
Constructors • Constructor is a class method with exactly the same name as class name • A constructor may accept argument(s) but does not return anything, not even void • They are called when an instance of the class is created • A default constructor does not accept any argument
Constructors (contd.) • If a default constructor is not provided, compiler assumes there exists but it does not do anything • Constructors can be overloaded in their argument type and number of arguments • In constructors, variables can be initialised to a default value • A copy constructor is used when objects are copied
Example: Constructors #include <iostream.h> class Customer // Specify a class name { private: int m_CustomerId; // Class data public: Customer() // no-arg or default constructor { m_CustomerId = 0; // default customer ID } Customer(int newCustomerId) // one-arg constructor { m_CustomerId = newCustomerId; } };
Example: Constructors void main() { Customer ordinaryCustomer; // creating instance using // default constructor Customer registeredCustomer(49); // creating instance // using one-arg constructor }
Copy Constructor • Copy constructor is used when objects are copied • Default copy constructor performs shallow copy • Explicit copy constructor can be provided to perform deep copy
Shallow and Deep Copy Initially Shallow Copy Deep Copy Employee Employee Employee m_pAddress m_pAddress m_pAddress name : e1 name : e1 name : e1 Address Address Address Address City : LHR State : Punjab Country : PK City : LHR State : Punjab Country : PK City : LHR State : Punjab Country : PK City : LHR State : Punjab Country : PK Employee Employee m_pAddress m_pAddress name : e2 name : e2
Example: Copy Constructor struct SAddress { char* city; char* state; char* country; SAddress() { city = ""; state = ""; country = ""; } void DisplayAddress() { cout << city << ", " << state << ", " << country << endl; } };
Example: Copy Constructor (contd.) class Employee { private: SAddress* m_pAddress; char* m_Name; public: Employee() { m_pAddress = 0; } ~Employee() { delete m_pAddress; }
Example: Copy Constructor (contd.) void SetAddress(char* city, char* state, char* country) { m_pAddress = new SAddress(); m_pAddress->city = city; m_pAddress->state = state; m_pAddress->country = country; } SAddress* GetAddress() { return m_pAddress; } void SetName(char* name) { m_Name = name; }
Example: Copy Constructor (contd.) char* GetName() { return m_Name; } void Display() { cout << m_Name << " -- "; m_pAddress->DisplayAddress(); } // this copy constructor performs deep copy Employee(Employee& e) { m_pAddress = new SAddress(); m_pAddress->city = e.GetAddress()->city; m_pAddress->state = e.GetAddress()->state; m_pAddress->country = e.GetAddress()->country; } };
Example: Copy Constructor (contd.) void main() { Employee e1; // no-arg constructor is called e1.SetName("E1"); e1.SetAddress("LHR", "Punjab", "PK"); e1.Display(); Employee e2 = e1; // copy constructor is called e2.SetName("E2"); e2.GetAddress()->city = ”ISB"; // change city for e2 e1.Display(); e2.Display(); }
Destructors • Called when an instance of the class is destroyed • Destructor is a class method starting with tilde (~) and have exactly the same name as class name • Destructors are used to release resources held by the instance (object) • Destructor does not accept any argument
Destructors (contd.) • Destructor does not return anything, not even void • Destructors can not be overloaded • Memory allocated by the instance is released after calling the destructor • Automatically called when the object goes out of scope
Example: Destructors #include <fstream.h> class MyFileHandler { private: ofstream m_file; public: MyFileHandler() { m_file.open(“myFile.txt”, ios::binary); } ~MyFileHandler() { m_file.close; }
Example: Destructors (contd.) void WriteToFile(int buff[1000]) { m_file.write((char*)buff, 1000*sizeof(int)); } }; void main() { int myData[1000]; MyFileHandler myFileHandler; for(int j=0; j < 1000; j++) { myData[j] = j; } myFilehandler.WriteToFile(myData); } // as myFileHandler goes out of scope, destructor is called // and the file is closed
Member Functions • Member functions are methods of a class, could be: • private, • protected or • public • Can be declared and defined together or separately • Inline function’s code is expanded where it is called and differ in normal function calling mechanism
Example: Member Functions #include <iostream.h> class Employee // Specify a class { private: int m_EmployeeId; // Class data int m_EmployeeAge; protected: // implicit inline function void ShowAge() // Member function to show { // Employee age cout << “\nAge is “ << m_EmployeeAge; }
Example: Member Functions (contd.) public: void SetId(int id) // Member function to set id { m_EmployeeId = id; } void ShowId(); // Declaration only void SetAge(int age); // Declaration only }; void Employee::ShowId() { cout << “\nId is “ << m_EmployeeId; } // explicit inline function inline void Employee::SetAge(int age) { m_EmployeeAge = age; }
Example: Member Functions (contd.) void main() { Employee manager, worker; // defining two objects manager.SetId(1001); // calling member function to // set Id worker.SetId(5001); // calling member function to // set Id manager.SetAge(45); // calling member function to set // manger’s age wroker.SetAge(45); // calling member function to set // worker’s age }
Static Data • Static data could be any type • Also called class data • Lifetime is the entire program • Shared among all objects of the same class • Static data members are accessed using class name and :: operator • In C++ static data is declared inside the class and defined outside the class
Example: Static Data class Counter // Specify a class { private: int m_Count; // class data public: void IncrementCount() { m_Count++; } int GetTotalCount() { return m_Count; } Counter() { m_Count = 0; } };
Example: Static Data(contd.) class Student { private: int m_StudentId; // class data int m_StudentClass; static Counter sm_Counter; // static counter to hold// count for all students public: void AddStudent(int id ,int studentClass) { m_StudentId = id; m_StudentClass= studentClass; sm_Counter.IncrementCount(); // increment count } int GetStudentsCount() // getting class id { return sm_Counter.GetTotalCount(); }
Example: Static Data(contd.) }; Counter Student::sm_Counter; // if we don’t write this line// compiler will give error void main() { Student newStudent; Student oldStudent; newStudent.AddStudent(100,10); oldStudent.AddStudent(23,10); cout << “\nTotal = “ << oldStudent.GetStudentsCount(); }
Difference Between Structures and Classes • The default access specifier in class is private, whereas in structure it is public • Structures are inherited as public by default • Classes are inherited as private by default
References • Available only in C++, not in C • One way to pass parameters to function is by reference • The variable passed by reference, if altered, changes the actual variable value • & is used to denote a reference, e.g. &p (where p is any data type) • References could be constant, called constant references, e.g. const &p
Example: References // Passing by reference example #include <iostream.h> void main() { void IntFrac(const float&, float&, float&); float number,intPart,fracPart; do { cout << “\nEnter a real number:”; cin >> number; Intfrac(number,intPart,fracPart); cout << “Integer part is “ << intPart << “, fraction part is “ << fracPart; }while (number != 0) }
Example: References (contd.) //IntFrac() // finds integer and fractional part of the real number void IntFrac(const float& n, float& intp, float& fracp) { intp = float(long(n)); fracp = n - intp; // n can not be changed inside the function as it is // constant reference }
Friend Classes and Functions • There are two types of friend modifiers: • Class Level • Function Level • A friend function can access the private data of that class • A friend function does not belong to a class, and • Its definition occurs outside the class without specifying the class name
Example: Friend Function / Class // friend function example #include <iostream.h> class Beta; // forward declaration of class Beta class Alpha { private: int m_Data; // class private data public; Alpha() { m_Data = 3; } // assigning class data friend int FriFunc(Alpha,Beta); // declaring friend // function friend Beta; // Beta is friend of // Alpha };
Example: Friend Function / Class (contd.) class Beta { private int m_Data; // class private data public: Beta() { m_Data = 7; } // assigning data void ChangeAlpha(Alpha& a); friend int FriFunc(Alpha,Beta); // declaraing friend }; // function int FriFunc(Alpha a, Beta b) // friend function { return (a.m_Data + b.m_Data); }
Example: Friend Function / Class (contd.) void Beta::ChangeAlpha(Alpha& a) { a.m_Data = 100; // change Alpha’s private data// as Beta is a friend of Alpha } void main() { Alpha aa; // define aa Beta bb; // define bb cout << FriFunc(aa,bb); // calling friend function bb.ChangeAlpha(aa); // change Alpha’s private data// through bb cout << FriFunc(aa,bb); // calling friend function }
Unit Summary In this unit you have covered … • Structures • Classes • Static data and member functions • References • Friend functions and classes