Objects and Classes
Objects and Classes
class Box {
public:
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box
};
#include <iostream>
class Box {
public:
int main() {
// box 1 specification
Box1.height = 5.0;
Box1.length = 6.0;
Box1.breadth = 7.0;
// box 2 specification
Box2.height = 10.0;
Box2.length = 12.0;
Box2.breadth = 13.0;
// volume of box 1
// volume of box 2
return 0;}
When the above code is compiled and executed, it produces the following
result −
4 Copy Constructor
The copy constructor is a constructor which creates an object by
initializing it with an object of the same class, which has been created
previously.
5 Friend Functions
A friend function is permitted full access to private and protected
members of a class.
6 Inline Functions
With an inline function, the compiler tries to expand the code in the
body of the function in place of a call to the function.
7 this Pointer
Every object has a special pointer this which points to the object itself.
C++ Inheritance
One of the most important concepts in object-oriented programming is
that of inheritance. Inheritance allows us to define a class in terms of
another class, which makes it easier to create and maintain an
application. This also provides an opportunity to reuse the code
functionality and fast implementation time.
When creating a class, instead of writing completely new data members
and member functions, the programmer can designate that the new class
should inherit the members of an existing class. This existing class is
called the base class, and the new class is referred to as
the derived class.
The idea of inheritance implements the is a relationship. For example,
mammal IS-A animal, dog IS-A mammal hence dog IS-A animal as well
and so on.
#include <iostream>
public:
void setWidth(int w) {
width = w;
void setHeight(int h) {
height = h;
protected:
int width;
int height;};
public:
int getArea() {
}};
int main(void) {
Rectangle Rect;
Rect.setWidth(5);
Rect.setHeight(7);
return 0;}
When the above code is compiled and executed, it produces the following
result −
Total area: 35
A derived class inherits all base class methods with the following
exceptions −
Type of Inheritance
When deriving a class from a base class, the base class may be inherited
through public, protected or private inheritance. The type of
inheritance is specified by the access-specifier as explained above.
We hardly use protected or private inheritance, but public inheritance
is commonly used. While using different type of inheritance, following
rules are applied −
Public Inheritance − When deriving a class from a public base
class, publicmembers of the base class become public members
of the derived class and protected members of the base class
become protected members of the derived class. A base
class's private members are never accessible directly from a
derived class, but can be accessed through calls to
the public and protectedmembers of the base class.
Protected Inheritance − When deriving from a protected base
class, publicand protected members of the base class
become protected members of the derived class.
Private Inheritance − When deriving from a private base
class, public and protected members of the base class
become private members of the derived class.
Multiple Inheritance
A C++ class can inherit members from more than one class and here is
the extended syntax −
#include <iostream>
public:
void setWidth(int w) {
width = w;
void setHeight(int h) {
height = h;
protected:
int width;
int height;};
public:
}};
int getArea() {
}};
int main(void) {
Rectangle Rect;
int area;
Rect.setWidth(5);
Rect.setHeight(7);
area = Rect.getArea();
cout << "Total paint cost: $" << Rect.getCost(area) << endl;
return 0;}
When the above code is compiled and executed, it produces the following
result −
Total area: 35
Total paint cost: $2450
C++ Overloading (Operator and
Function)
C++ allows you to specify more than one definition for a function name
or an operator in the same scope, which is called function
overloading and operator overloadingrespectively.
An overloaded declaration is a declaration that is declared with the same
name as a previously declared declaration in the same scope, except that
both declarations have different arguments and obviously different
definition (implementation).
When you call an overloaded function or operator, the compiler
determines the most appropriate definition to use, by comparing the
argument types you have used to call the function or operator with the
parameter types specified in the definitions. The process of selecting the
most appropriate overloaded function or operator is called overload
resolution.
class printData {
public:
void print(int i) {
void print(double f) {
void print(char* c) {
}};
int main(void) {
printData pd;
pd.print(5);
pd.print(500.263);
pd.print("Hello C++");
return 0;}
When the above code is compiled and executed, it produces the following
result −
Printing int: 5
Printing float: 500.263
Printing character: Hello C++
declares the addition operator that can be used to add two Box objects
and returns final Box object. Most overloaded operators may be defined
as ordinary non-member functions or as class member functions. In case
we define above function as non-member function of a class then we
would have to pass two arguments for each operand as follows −
class Box {
public:
double getVolume(void) {
length = len;
breadth = bre;
}
void setHeight( double hei ) {
height = hei;
Box box;
return box;
private:
// box 1 specification
Box1.setLength(6.0);
Box1.setBreadth(7.0);
Box1.setHeight(5.0);
// box 2 specification
Box2.setLength(12.0);
Box2.setBreadth(13.0);
Box2.setHeight(10.0);
// volume of box 1
volume = Box1.getVolume();
// volume of box 2
volume = Box2.getVolume();
// volume of box 3
volume = Box3.getVolume();
return 0;}
When the above code is compiled and executed, it produces the following
result −
Volume of Box1 : 210
Volume of Box2 : 1560
Volume of Box3 : 5400
Overloadable/Non-overloadableOperators
Following is the list of operators which can be overloaded −
+ - * / % ^
& | ~ ! , =
+= -= /= %= ^= &=
|= *= <<= >>= [] ()
:: .* . ?:
Polymorphism in C++
class Shape {
protected:
public:
width = a;
height = b;
}
int area() {
return 0;
public:
int area () {
}};
public:
int area () {
}};
Shape *shape;
Rectangle rec(10,7);
Triangle tri(10,5);
shape->area();
shape = &tri;
shape->area();
return 0;}
When the above code is compiled and executed, it produces the following
result −
The reason for the incorrect output is that the call of the function area()
is being set once by the compiler as the version defined in the base class.
This is called static resolutionof the function call, or static linkage -
the function call is fixed before the program is executed. This is also
sometimes called early binding because the area() function is set during
the compilation of the program.
But now, let's make a slight modification in our program and precede the
declaration of area() in the Shape class with the keyword virtual so that
it looks like this −
class Shape {
protected:
int width, height;
public:
Shape( int a = 0, int b = 0) {
width = a;
height = b;
}
virtual int area() {
cout << "Parent class area :" <<endl;
return 0;
}
};
This time, the compiler looks at the contents of the pointer instead of it's
type. Hence, since addresses of objects of tri and rec classes are stored
in *shape the respective area() function is called.
As you can see, each of the child classes has a separate implementation
for the function area(). This is how polymorphism is generally used. You
have different classes with a function of the same name, and even the
same parameters, but with different implementations.
Virtual Function
A virtual function is a function in a base class that is declared using the
keyword virtual. Defining in a base class a virtual function, with another
version in a derived class, signals to the compiler that we don't want
static linkage for this function.
What we do want is the selection of the function to be called at any given
point in the program to be based on the kind of object for which it is
called. This sort of operation is referred to as dynamic linkage, or late
binding.
class Shape {
protected:
int width, height;
public:
Shape(int a = 0, int b = 0) {
width = a;
height = b;
}
The = 0 tells the compiler that the function has no body and above
virtual function will be called pure virtual function.
int main() {
return 0;}
Members defined with a public label are accessible to all parts of
the program. The data-abstraction view of a type is defined by its
public members.
Members defined with a private label are not accessible to code
that uses the class. The private sections hide the implementation
from code that uses the type.
There are no restrictions on how often an access label may appear. Each
access label specifies the access level of the succeeding member
definitions. The specified access level remains in effect until the next
access label is encountered or the closing right brace of the class body is
seen.
Class internals are protected from inadvertent user-level errors,
which might corrupt the state of the object.
The class implementation may evolve over time in response to
changing requirements or bug reports without requiring change in
user-level code.
By defining data members only in the private section of the class, the
class author is free to make changes in the data. If the implementation
changes, only the class code needs to be examined to see what affect the
change may have. If data is public, then any function that directly access
the data members of the old representation might be broken.
class Adder {
public:
// constructor
Adder(int i = 0) {
total = i;
total += number;
}
// interface to outside world
int getTotal() {
return total;
};
private:
int total;};
int main() {
Adder a;
a.addNum(10);
a.addNum(20);
a.addNum(30);
return 0;}
When the above code is compiled and executed, it produces the following
result −
Total 60
Above class adds numbers together, and returns the sum. The public
members - addNumand getTotal are the interfaces to the outside world
and a user needs to know them to use the class. The private
member total is something that the user doesn't need to know about,
but is needed for the class to operate properly.
Designing Strategy
Abstraction separates code into interface and implementation. So while
designing your component, you must keep interface independent of the
implementation so that if you change underlying implementation then
interface would remain intact.
In this case whatever programs are using these interfaces, they would
not be impacted and would just need a recompilation with the latest
implementation.
Program statements (code) − This is the part of a program that
performs actions and they are called functions.
Program data − The data is the information of the program which
gets affected by the program functions.
Encapsulation is an Object Oriented Programming concept that binds
together the data and functions that manipulate the data, and that keeps
both safe from outside interference and misuse. Data encapsulation led
to the important OOP concept of data hiding.
Data encapsulation is a mechanism of bundling the data, and the
functions that use them and data abstraction is a mechanism of
exposing only the interfaces and hiding the implementation details from
the user.
C++ supports the properties of encapsulation and data hiding through
the creation of user-defined types, called classes. We already have
studied that a class can contain private,
protected and public members. By default, all items defined in a class
are private. For example −
class Box {
public:
double getVolume(void) {
return length * breadth * height;
}
private:
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box
};
The variables length, breadth, and height are private. This means that
they can be accessed only by other members of the Box class, and not by
any other part of your program. This is one way encapsulation is
achieved.
To make parts of a class public (i.e., accessible to other parts of your
program), you must declare them after the public keyword. All variables
or functions defined after the public specifier are accessible by all other
functions in your program.
Making one class a friend of another exposes the implementation details
and reduces encapsulation. The ideal is to keep as many of the details of
each class hidden from all other classes as possible.
class Adder {
public:
// constructor
Adder(int i = 0) {
total = i;
}
// interface to outside world
total += number;
int getTotal() {
return total;
};
private:
int total;};
int main() {
Adder a;
a.addNum(10);
a.addNum(20);
a.addNum(30);
return 0;}
When the above code is compiled and executed, it produces the following
result −
Total 60
Above class adds numbers together, and returns the sum. The public
members addNumand getTotal are the interfaces to the outside world
and a user needs to know them to use the class. The private
member total is something that is hidden from the outside world, but is
needed for the class to operate properly.
Designing Strategy
Most of us have learnt to make class members private by default unless
we really need to expose them. That's just good encapsulation.
This is applied most frequently to data members, but it applies equally to
all members, including virtual functions.
class Box {
public:
// pure virtual function
virtual double getVolume() = 0;
private:
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box
};
#include <iostream>
public:
void setWidth(int w) {
width = w;
void setHeight(int h) {
height = h;
protected:
int width;
int height;};
public:
int getArea() {
}};
public:
int getArea() {
}};
int main(void) {
Rectangle Rect;
Triangle Tri;
Rect.setWidth(5);
Rect.setHeight(7);
cout << "Total Rectangle area: " << Rect.getArea() << endl;
Tri.setWidth(5);
Tri.setHeight(7);
cout << "Total Triangle area: " << Tri.getArea() << endl;
return 0;}
When the above code is compiled and executed, it produces the following
result −
Designing Strategy
An object-oriented system might use an abstract base class to provide a
common and standardized interface appropriate for all the external
applications. Then, through inheritance from that abstract base class,
derived classes are formed that operate similarly.
The capabilities (i.e., the public functions) offered by the external
applications are provided as pure virtual functions in the abstract base
class. The implementations of these pure virtual functions are provided in
the derived classes that correspond to the specific types of the
application.
This architecture also allows new applications to be added to a system
easily, even after the system has been defined.