0% found this document useful (0 votes)
20 views

CPlus Plus

The document discusses C++ programming concepts including data types, arrays, structures, classes, objects, and member functions. It provides examples and explanations of primitive and composite data types, one and two dimensional arrays, defining structures and classes, and creating and using objects.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
20 views

CPlus Plus

The document discusses C++ programming concepts including data types, arrays, structures, classes, objects, and member functions. It provides examples and explanations of primitive and composite data types, one and two dimensional arrays, defining structures and classes, and creating and using objects.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 46

C++ Programming

CSE225: Data Structures and Algorithms


The Hello Program
#include <iostream>
using namespace std;

int main()
{
char name[100];
cout << "Enter your name: ";
cin >> name; //scanf
cout << "Hello " <<name<<endl; //printf
return 0;
}
C++ has two types of data types:

1. Primitive Data Type:


- Basic Unit of Language
- Each Primitive value is a single datum
Example: int , char, float, etc.

• 2. Composite Data Type:


- Multiple pieces of related data as a single datum
Example: array, structure, class, etc.

** What are the differences between Primitive and


Composite Data Types??
Array

• Stores a fixed-size sequential collection of elements of the same type.


• All arrays consist of contiguous memory locations. The lowest address
corresponds to the first element and the highest address to the last
element.
• Declaration:
DataType ArrayName[dimension] = { element1, element2, …, elementn};

• One-dimensional Array
• Two –dimensional Array
Structure
- A linear, direct access data structure with
heterogeneous components
- A component is also called a field or a member
- Each field has its own type
- An identifier is used to name a field/component
Example:

struct CarType {
int year;
char maker[10];
float price;
};
CarType MyCar;//in C++ CarType is considered a data type
//name; unlike C where you have to write struct CarType
Class and Object
• Class is a data type that encapsulates a fixed number of data
components with the functions that can access and/or manipulate them
• It gives the C++ its identity from C
• It makes possible encapsulation, data hiding and inheritance
• Consists of both data and methods
• Defines properties and behavior of a set of entities
• Abstract concept: liken to the specification of a laptop
• Object
• An instance of a class
• A variable identified by a unique name
• Concrete concept: liken to an actual laptop having a given specification
Objects
Object:
a variable or an instance of a class

OBJECT
set of methods
Operations (public member functions)

Data
internal state
(values of private data members)
Motivation for classes
• Object-Oriented Programming (OOP)
• Package together a set of related data and operations
(encapsulation)
• Allows programmer to define a class (abstract data type)
• One instance (variable) of a class is called an object
• The data and operations of a class are called its
members.
A Class & Its Objects
class Rectangle Rectangle r1;
{ Rectangle r2;
Rectangle r3;
private://by default
int width;
int length;
public:
void set(int w, int l);
int area();
};
Define a Class Type
class Rectangle
class class_name {
{ private:
permission_label:
int width;
member;
permission_label: int length;
member; public:
... void set(int w, int l);
};
int area();
};
Another Example //Circle.cpp file
//Circle.h file // member function definitions
#include <iostream.h> circle::circle(){radius = 0.0;}
void display (double r){
class circle cout << r << endl;
{ }
private:
double radius; void circle:: store(double r){
radius = r;
public: }
circle(); double circle::area(){
void store(double); return 3.14*radius*radius;
double area(); }
void display(); void circle::display(){
}; cout << “r = “ << radius << endl;
void display(double r); }

//main.cpp file
int main(void) {
circle c; // an object of circle class
c.store(5.0); cout << "The area of circle c is " << c.area() << endl;
c.display();
}
Class Definition - Access Control
• Information hiding
• To prevent the internal representation from direct access from
outside the class
• Access Specifiers
• public
• may be accessible from anywhere within a program
• private
• may be accessed only by the member functions, and friends
of this class, not accessible to nonmember functions
• Protected
• Accessible only to derived/child + same class member
functions
• Difference between classes and structs in C++
the default access specifier is private in class
the default access specifier is public in struct
Class Definition – Member Functions
• Used to
• access the values of the data members (accessor/get method)
• perform operations on the data members (modifier/set method)
• Are declared inside the class body, in the same way as
declaring a function
• Their definition can be placed inside the class body, or
outside the class body
• Can access both public and private members of the class
• Can be called using dot (for an object) or arrow (for a
pointer to an object) member access operator
Define a Member Function
class Rectangle
{
private:
int width, length;
public:
void set (int w, int l){width=w;length=l;}
int area() {return width*length; }
}

Rectangle r1;
r1.set(5,8);

Rectangle *rp=&r1;
rp -> set(8,10);//equivalent to: r1.set(8,10); or (*rp).set(8,10);
Defining Methods Separately
• For methods/functions that are declared but not defined in the class we
need to provide a separate definition
• To define the method, you define it as any other function, except that
the name of the function is written as:-

ClassName::FuncName
:: is the scope resolution operator, it allows us to refer to parts of a class or
structure
Defining Member Functions
class Rectangle
{
private:
int width, length; class name
public:
void set (int w, int l);
member function name
int area() {return width*length; }
}

void Rectangle :: set (int w, int l)


Rectangle r1; {
r1.set(5,8); width = w;
length = l; scope operator
Rectangle *rp;
rp->set(8,10); }
Inline Functions
• In an inline function, the C++ compiler does not make a
function call, instead the code of the function is inserted (in .exe
file) in place of the function call (and appropriate argument
substitutions are made)
• Why used?
• It saves the memory space when a function is likely to be called many
times (no stack push happens)
• When we need to make the function call very fast.
• E.g. for accessing/changing fields of a class (set/get methods)
• Compiler replaces the definition of inline functions at compile time
instead of referring function definition at runtime.
• Typically done for simple/small functions; because otherwise exe file
will become very large
• Inline functions’ declaration and definition can’t be split into .h and
.cpp files
inline int sum(int a, int b)
{ return a+b; }//inline is a keyword that
//tells the compiler that this
//function is inline
Member Functions defined within class
declaration are automatically inline functions

class Rectangle
{
private:
int width, length;
public:
void set (int w, int l);
int area() {return width*length; }
}

Automatically inline function;


no need to use inline keyword
before function header
Three Types of Functions
• Class member functions are classified into three categories:
• Constructors
• create objects (allocate memory, set initial state)
• Modifiers/set-methods
• change the state of objects
• Accessors/get-methods
• make information about the state of the object available outside the class
Constructor
• Goal:
• construct objects of the class
• allocate memory
• Constructors MUST have the same name as the class itself.
• They don't have a return type. It's simply omitted.

• That's how you'll make instances of the class (objects).


• Example:
• Constructor of dateType class
• dateType();
• Constructor of rectangle class
• rectangle();
Constructor (Cont.)
• Constructors can be overloaded, i.e., a class can have several
constructors that have the same name but different lists of parameters
• This ability allows us to create
• A default constructor: no parameters
• Initializer constructors: parameters specifying initial state of an object
• A copy constructor
• Called when an object is copied to another object of the same type
• Copy constructor is called when we:
• Initialize one object from another of the same type.
• Copy an object to pass it as an argument to a function.
• Copy an object to return it from a function.
• If no copy constructors is declared in the class, then an object is bitwise copied to
another object in the above 3 cases – which may be problematic especially if the
objects contain any pointer. That’s why it’s a good practice to put a copy constructor.
Constructor Example
class Rectangle{
public:
int width, length;
Rectangle(){width=length=0;} //default constructor
Rectangle(int w, int l){width=w; length=l;} //constructor with initializers
//copy constructor
Rectangle(const Rectangle &r){width=r.width; length=r.length;}
};
void print(Rectangle r){cout << r.width << ‘ ‘ << r.length << endl;}
Rectanlgle create(int w, int l){Rectangle r; r.width=w; r.length= l; return r;}

Rectangle r1; //default constructor is called


Rectangle r2(5,3.4); //initializer constructor is called
Rectangle r3= r2; //copy constructor is called: r3.Rectangle(r2);
print(r3); //copy constructor is called: Rectangle r = r3;//r.Rectangle(r3);
Rectangle t= create(4,2); //copy constructor is called: Rectangle t = r;
Destructor Function
• A destructor is a special member function that is called when the
lifetime of an object ends.
• The purpose of the destructor is to free the resources that the object
may have acquired during its lifetime.
• In a C++ class, destructor should be provided when memory is
dynamically allocated for some members of that class, because C++
doesn’t have an automatic garbage collection mechanism (unlike
Java)
• Destructor syntax:
~ class_name ();
Destructor Example
#include <iostream>
using namespace std;

struct A{
int *i;
A (int k) {
i = new int;
*i = k;
cout << “ctor ” << *i << '\n';
}
~A() {cout << “dtor ” << *i << '\n'; delete i;} //destructor
};

int main(){
A a1(1);//constructor is called to instantiate a1
if(1){ // nested scope
A a2(2); //constructor is called to instantiate a2
} // a2 out of scope; so destructor is called on a2
} // a1 out of scope; so destructor is called on a1
Destructor Example Output
ctor a1
ctor a2
dtor a2
dtor a1
Basics

• For every data structure, we will create 3 files in our Codeblocks


project
• The declaration file (with .h extension)
• The definition file (with .cpp extension)
• The driver file (with .cpp extension)
Class in a Separate Header File for Reusability

• Header files
• Separate files in which class definitions are placed.
• Allow compiler to recognize the classes when used elsewhere.
• Generally have .h filename extensions

• .cpp files for source-code implementations


• Class implementations
• Main programs
• Test programs

• Driver file
• A program used to test software (such as classes).
• Contains a main function so it can be executed
Basics
#ifndef DYNARR_H_INCLUDED
#define DYNARR_H_INCLUDED

class dynArr
{
private:
int *data;
int size;

public:
dynArr();
dynArr(int);
~dynArr();
void allocate(int);
void setValue(int, int);
int getValue(int);
};

#endif // DYNARR_H_INCLUDED

dynarr.h (header file)


Basics
#include "dynarr.h" void dynArr::allocate(int s)
#include <iostream> {
using namespace std; if(data!=NULL) delete [] data;
data = new int[s];
dynArr::dynArr() size = s;
{ }
data = NULL;
size = 0; int dynArr::getValue(int index)
} {
return data[index];
dynArr::dynArr(int s) }
{
data = new int[s]; void dynArr::setValue(int index, int
size = s; value)
} {
data[index] = value;
dynArr::~dynArr() }
{
if(data!=NULL)
delete [] data;
} dynarr.cpp (definition file)
Basics
#include "dynarr.h"
#include <iostream>
using namespace std;

int main()
{
int n;
cin>>n;
dynArr d(n);
int i;

for(i=0;i<n;i++)
d. setValue(i,3*i+1);
for(i=0;i<n;i++)
cout << d.getValue(i) << endl;
d.allocate(100);//reallocate space
for(i=0;i<n;i++)
cout << d.getValue(i) << endl; //prints garbage values
return 0;
}
main.cpp (driver file)
Template Class

• Now we have a neat class that gives us a 1D dynamic array (you are free to make
your own improvisations at home by adding more functions to the class)
• But it only works for integer type
• What if we are to make it versatile, so that it works for any type, e.g. float,
double and char
• Should we have separate classes for each type?
• Write the same code for each type with just minor changes?
• Instead, we can use template classes
Template Class
#ifndef DYNARR_H_INCLUDED
#define DYNARR_H_INCLUDED

template <class T>


class dynArr
{
private:
T *data;
int size;

public:
dynArr();
dynArr(int);
~dynArr();
void allocate(int);
void setValue(int, T);
T getValue(int);
};

#endif // DYNARR_H_INCLUDED
dynarr.h (declaration file)
Template Class
#include "dynarr.h" template <class T>
#include <iostream> void dynArr<T>::allocate(int s)
using namespace std; {
if(data!=NULL) delete [] data;
template <class T> data = new T[s];
dynArr<T>::dynArr() size = s;
{
}
data = NULL;
size = 0;
} template <class T>
T dynArr<T>::getValue(int index)
template <class T> {
dynArr<T>::dynArr(int s) return data[index];
{ }
data = new T[s];
size = s;
template <class T>
}
void dynArr<T>::setValue(int index, T
template <class T> value)
dynArr<T>::~dynArr() {
{ data[index] = value;
delete [] data; }
} dynarr.cpp (definition file)
Template Class
#include "dynarr.cpp"
#include <iostream>
using namespace std;

int main()
{
dynArr<int> di(10);
dynArr<double> dd(10);
int i;

for(i=0;i<10;i++)
{
di.setValue(i,3*i+1);
dd.setValue(i,7.29*i/1.45);
}
for(i=0;i<10;i++)
cout << di.getValue(i) << " " << dd.getValue(i) << endl;

return 0;
}
main.cpp (driver file)
A Complex Number Example
class Complex
{ Complex Complex::Add(Complex c)
public: {
Complex(); Complex t;
Complex(double, double); t.Real = Real + c.Real;
Complex Add(Complex); t.Imaginary = Imaginary + c.Imaginary;
void Print(); return t;
private: }
double Real, Imaginary; void Complex::Print()
}; {
cout << Real << endl;
Complex::Complex() cout << Imaginary << endl;
{ }
Real = 0;
Imaginary = 0;
} int main(void)
{
Complex::Complex(double r, double i) Complex A(1,1), B(2,3);
{ Complex C;
Real = r; C = A.Add(B);
Imaginary = i; C.Print();
} return 0;
}
Friend Function

• The function has access to the private members in the class


declaration
• The function is outside the scope of the class
Friend Function
class Complex
{
public:
Complex();
Complex(double, double);
void Print();
friend Complex AddComplex(Complex, Complex);
private:
double Real, Imaginary;
};

Complex::Complex()
{
Real = 0;
Imaginary = 0;
}

Complex::Complex(double r, double i)
{
Real = r;
Imaginary = i;
}
Friend Function
void Complex::Print()
{
cout << Real << endl;
cout << Imaginary << endl;
}

Complex AddComplex(Complex a, Complex b)


{
Complex t;
t.Real = a.Real + b.Real;
t.Imaginary = a.Imaginary + b.Imaginary;
return t;
}

int main(void)
{
Complex A(1,1), B(2,3);
Complex C;
C = AddComplex(A, B);
C.Print();
return 0;
}
Operator Overloading

• We can use some operator symbols to define special member functions of a class

• Provides convenient notations for object behaviors


Operator Overloading
class Complex
{
public:
Complex();
Complex(double, double);
Complex operator+(Complex);
Complex operator+(double);
void Print();
private:
double Real, Imaginary;
};

Complex::Complex()
{
Real = 0;
Imaginary = 0;
}

Complex::Complex(double r, double i)
{
Real = r;
Imaginary = i;
}
Operator Overloading
Complex Complex::operator+(Complex a){
Complex t;
t.Real = Real + a.Real;
t.Imaginary = Imaginary + a.Imaginary;
return t;
}

Complex Complex::operator+(double n){


Complex t;
t.Real = Real + n;
t.Imaginary = Imaginary + n;
return t;
}

void Complex::Print(){
cout << Real << endl;
cout << Imaginary << endl;
}

int main(void) {
Complex A(1,1), B(2,3), D(5,6), C;
C = A + B; //C = A.operator+(B);
C = C + 3.2; //C = C.operator+(3.2);
C.Print();
return 0;
}
Operator Overloading using friend
function
 With simple operator overloading we can’t do:
Complex A, C = 3.2+A;

 To be able to write expressions like above, we need friend operator


function
Operator Overloading with friend function
class Complex
{
double Real, Imaginary; //private, by default
public:
Complex();
Complex(double, double);
friend Complex operator+(double, Complex);
friend Complex operator+(Complex, double);
// Complex operator+(double n)
friend Complex operator++(Complex&);
void Print();
};

Complex::Complex()
{
Real = 0;
Imaginary = 0;
}

Complex::Complex(double r, double i)
{
Real = r;
Imaginary = i;
}
Operator Overloading with friend function
Complex operator+(double n, Complex a){
Complex t;
t.Real = n + a.Real;
t.Imaginary = n + a.Imaginary;
return t;
}
Complex operator+(Complex a, double n){
Complex t;
t.Real = n + a.Real;
t.Imaginary = n + a.Imaginary;
return t;
}
Complex operator++(Complex &a) {
a.Real ++; a.Imaginary ++;
return a;
}
void Complex::Print(){
cout << Real << endl << Imaginary << endl;
}
int main(void) {
Complex A(1,1), B;
B = 3.2 + A;//operator+(3.2, A);
A = A + 2.4;
B=++A;//operator++(A);//a=A
A.Print();B.Print();
return 0;
}
Overloading Relational Operator
class Complex
{
public:
Complex();
Complex(double, double);
bool operator>(Complex);
void Print();
private:
double Real, Imaginary;
};

Complex::Complex()
{
Real = 0;
Imaginary = 0;
}

Complex::Complex(double r, double i)
{
Real = r;
Imaginary = i;
}
Overloading Relational Operator
bool Complex::operator>(Complex a){
if(Real > a.Real || (Real == a.Real && Imaginary > a.Imaginary))
return true;
else
return false;
}
void Complex::Print(){
cout << Real << endl;cout << Imaginary << endl;
}
int main(void) {
Complex A(1,1), B;
A.Print();
B.Print();
if(A>B) //A.operator>(B);
cout<<“A is greater”;
return 0;
}

You might also like