Notes Oopm Unit 2
Notes Oopm Unit 2
Unit-2/ Lecture-1
Note: The following class diagrams were modelled using Enterprise Architect. Many other
modelling tools exist. Use the one that is best suited for your purpose and project.
Classes
Object-oriented classes support the object-oriented principles of abstraction,
encapsulation, polymorphism and reusability. They do so by providing a template, or
blueprint, that defines the variables and the methods common to all objects that are
based on it. Classes specify knowledge (attributes) - they know things - and behaviour
(methods) - they do things.
Attributes:-
Attributes define the characteristics of the class that, collectively, capture all the
information about the class. Attributes should be protected by their enclosing class.
Unless changed by the class’ behavior, attributes maintain their values.
The type of data that an attribute can contain is determined by its data type. There are
two basic data types: Primitive and Derived.
Primitive data types are fundamental types. Examples are integer, string, float.
Derived data types are defined in terms of the Primitive data types, that is, they form
new data types by extending the primitive data types. A Student class, for example, is a
derived data type formed by a collection of primitive data types.
When defined in the context of a problem domain, derived data types are called Domain
Specific Data types. These are the types that define and constrain attributes to be
consistent with the semantics of the data. For example, Address student
Address versus string student Address.
Object composition
programming.
When, in a language, objects are typed, types can often be divided into composite and
non composite types, and composition can be regarded as a relationship between types:
an object of a composite type (e.g. car) "has an" object of a simpler type (e.g. wheel).
Composition must be distinguished from sub typing, which is the process of adding detail
to a general data type to create a more specific data type. For instance, cars may be a
specific type of vehicle: car is a vehicle. Sub typing doesn't describe a relationship
between different objects, but instead, says that objects of a type are simultaneously
objects of another type.
Unit-2/Lecture-3
The whole point of OOP is that your code replicates real world objects, thus making your
code readable and maintainable. When we say real world, the real world has
relationships. Let’s consider the simple requirement listed below:
1. Manager is an employee of XYZ limited corporation.
2. Manager uses a swipe card to enter XYZ premises.
3. Manager has workers who work under him.
4. Manager has the responsibility of ensuring that the project is successful.
5. Manager's salary will be judged based on project success.
If you flesh out the above five point requirement, we can easily visualize four
relationships:-
Inheritance
Aggregation
Association
Composition
Let’s understand them one by one.
The first expression is used to allocate memory to contain one single element of
type type. The second one is used to allocate a block (an array) of elements of type type,
where number_of_elements is an integer value representing the amount of these. For
example:
1 int * foo;
2 foo = new int [5];
In this case, the system dynamically allocates space for five elements of type int and
returns a pointer to the first element of the sequence, which is assigned to foo (a
pointer). Therefore, foo now points to a valid block of memory with space for five
elements of type int.
Here, foo is a pointer, and thus, the first element pointed to by foo can be accessed
either with the expressionfoo[0] or the expression *foo (both are equivalent). The second
element can be accessed either with foo[1] or *(foo+1), and so on...
The dynamic memory requested by our program is allocated by the system from the
memory heap. However, computer memory is a limited resource, and it can be
exhausted. Therefore, there are no guarantees that all requests to allocate memory using
operator new are going to be granted by the system.
C++ provides two standard mechanisms to check if the allocation was successful:
This exception method is the method used by default by new, and is the one used in a
declaration like:
foo = new int [5]; // if allocation fails, an exception is thrown
The other method is known as nothrow, and what happens when it is used is that when a
memory allocation fails, instead of throwing a bad_alloc exception or terminating the
program, the pointer returned by new is a null pointer, and the program continues its
execution normally.
This method can be specified by using a special object called nothrow, declared in
header <new>, as argument fornew:
foo = new (nothrow) int [5];
In this case, if the allocation of this block of memory fails, the failure can be detected by
checking if foo is a null pointer:
int * foo;
foo = new (nothrow) int [5];
if (foo == nullptr) {
// error assigning memory. Take measures.
}
This no throw method is likely to produce less efficient code than exceptions, since it
implies explicitly checking the pointer value returned after each and every allocation.
Therefore, the exception mechanism is generally preferred, at least for critical
allocations. Still, most of the coming examples will use the no throw mechanism due to
its simplicity.
Unit-2/Lecture-4
The second use of the operator is used to access the members declared in class scope.
Whenever a scope resolution operator is used the name of the member that follows the
operator is looked up in the scope of the class with the name that appears before the
operator.
The scope resolution operator (::) in C++ is used to define the already declared member
functions (in the header file with the .hpp or the .h extension) of a particular class. In the
.cpp file one can define the usual global functions or the member functions of the class.
To differentiate between the normal functions and the member functions of the class,
one needs to use the scope resolution operator (::) in between the class name and the
member function name i.e. ship::foo() where ship is a class and foo() is a member
function of the class ship. The other uses of the resolution operator is to resolve the
scope of a variable when the same identifier is used to represent a global variable, a local
variable, and members of one or more class(es). If the resolution operator is placed
between the class name and the data member belonging to the class then the data name
belonging to the particular class is referenced. If the resolution operator is placed in front
of the variable name then the global variable is referenced. When no resolution operator
is placed then the local variable is referenced.
#include <iostream>
using namespace std;
int n = 12; // A global variable
int main() {
int n = 13; // A local variable
cout << ::n << endl; // Print the global variable: 12
cout << n << endl; // Print the local variable: 13
}
Here, the value of a is promoted from short to int without the need of any explicit
operator. This is known as a standard conversion. Standard conversions affect
fundamental data types, and allow the conversions between numerical types (short to
int, int to float, double to int...), to or from bool, and some pointer conversions.
Converting to int from some smaller integer type, or to double from float is known as
promotion, and is guaranteed to produce the exact same value in the destination type.
Other conversions between arithmetic types may not always be able to represent the
same value exactly:
If the conversion is from a floating-point type to an integer type, the value is truncated
(the decimal part is removed). If the result lies outside the range of representable values
by the type, the conversion causes undefined behavior.
Otherwise, if the conversion is between numeric types of the same kind (integer-to-
integer or floating-to-floating), the conversion is valid, but the value is implementation-
specific (and may not be portable).
Some of these conversions may imply a loss of precision, which the compiler can signal
with a warning. This warning can be avoided with an explicit conversion.
For non-fundamental types, arrays and functions implicitly convert to pointers, and
pointers in general allow the following conversions:
Null pointers can be converted to pointers of any type
Pointers to any type can be converted to void pointers.
Pointer upcast: pointers to a derived class can be converted to a pointer of an accessible
and unambiguous base class, without modifying its const or volatile qualification.
assignments.
Type-cast operator: allow implicit conversion to a particular type.
For example:
// implicit conversion of classes:
#include <iostream>
using namespace std;
class A {};
class B {
public:
// conversion from A (constructor):
B (const A& x) {}
// conversion from A (assignment):
B& operator= (const A& x) {return *this;}
// conversion to A (type-cast operator)
operator A() {return A();}
};
int main ()
{
A foo;
B bar = foo; // calls constructor
bar = foo; // calls assignment
foo = bar; // calls type-cast operator
return 0;
}
The type-cast operator uses a particular syntax: it uses the operator keyword followed by
the destination type and an empty set of parentheses. Notice that the return type is the
destination type and thus is not specified before the operator keyword.
Keyword explicit
On a function call, C++ allows one implicit conversion to happen for each argument. This
may be somewhat problematic for classes, because it is not always what is intended. For
example, if we add the following function to the last example:
void fn (B arg) {}
This function takes an argument of type B, but it could as well be called with an object of
type A as argument:
fn (foo);
This may or may not be what was intended. But, in any case, it can be prevented by
marking the affected constructor with the explicit keyword:
// explicit:
#include <iostream>
using namespace std;
class A {};
class B {
public:
we dont take any liability for the notes correctness. http://www.rgpvonline.com
11
Additionally, constructors marked with explicit cannot be called with the assignment-like
syntax; In the above example, bar could not have been constructed with:
B bar = foo;
Type-cast member functions (those described in the previous section) can also be
specified as explicit. This prevents implicit conversions in the same way as explicit-
specified constructors do for the destination type.
class Dummy {
double i,j;
};
we dont take any liability for the notes correctness. http://www.rgpvonline.com
12
class Addition {
int x,y;
public:
Addition (int a, int b) { x=a; y=b; }
int result() { return x+y;}
};
int main () {
Dummy d;
Addition * padd;
padd = (Addition*) &d;
cout << padd->result();
return 0;
}
In order to control these types of conversions between classes, we have four specific
casting operators: dynamic_cast, reinterpret_cast, static_cast and const_cast. Their
format is to follow the new type enclosed between angle-brackets (<>) and immediately
after, the expression to be converted between parentheses.
dynamic_cast
dynamic_cast can only be used with pointers and references to classes (or with void*). Its
purpose is to ensure that the result of the type conversion points to a valid complete
object of the destination pointer type.
polymorphic classes (those with virtual members) if -and only if- the pointed object is a
valid complete object of the target type. For example:
// dynamic_cast
#include <iostream>
#include <exception>
using namespace std;
int main () {
try {
Base * pba = new Derived;
Base * pbb = new Base;
Null pointer on second type-
Derived * pd;
cast.
pd = dynamic_cast<Derived*>(pba);
if (pd==0) cout << "Null pointer on first type-cast.\n";
pd = dynamic_cast<Derived*>(pbb);
if (pd==0) cout << "Null pointer on second type-
cast.\n";
The code above tries to perform two dynamic casts from pointer objects of type Base*
(pba and pbb) to a pointer object of type Derived*, but only the first one is successful.
Notice their respective initializations:
Base * pba = new Derived;
Base * pbb = new Base;
Even though both are pointers of type Base*, pba actually points to an object of type
Derived, while pbb points to an object of type Base. Therefore, when their respective
type-casts are performed using dynamic_cast, pba is pointing to a full object of class
Derived, whereas pbb is pointing to an object of class Base, which is an incomplete object
of class Derived.
When dynamic_cast cannot cast a pointer because it is not a complete object of the
required class -as in the second conversion in the previous example- it returns a null
pointer to indicate the failure. If dynamic_cast is used to convert to a reference type and
the conversion is not possible, an exception of type bad_cast is thrown instead.
dynamic_cast can also perform the other implicit casts allowed on pointers: casting null
we dont take any liability for the notes correctness. http://www.rgpvonline.com
14
pointers between pointers types (even between unrelated classes), and casting any
pointer of any type to a void* pointer.
static_cast
static_cast can perform conversions between pointers to related classes, not only upcasts
(from pointer-to-derived to pointer-to-base), but also downcasts (from pointer-to-base to
pointer-to-derived). No checks are performed during runtime to guarantee that the
object being converted is in fact a full object of the destination type. Therefore, it is up to
the programmer to ensure that the conversion is safe. On the other side, it does not incur
the overhead of the type-safety checks of dynamic_cast.
class Base {};
class Derived: public Base {};
Base * a = new Base;
Derived * b = static_cast<Derived*>(a);
This would be valid code, although b would point to an incomplete object of the class and
could lead to runtime errors if dereferenced.
Therefore, static_cast is able to perform with pointers to classes not only the conversions
allowed implicitly, but also their opposite conversions.
static_cast is also able to perform all conversions allowed implicitly (not only those with
pointers to classes), and is also able to perform the opposite of these. It can:
Convert from void* to any pointer type. In this case, it guarantees that if the void*
value was obtained by converting from that same pointer type, the resulting pointer
value is the same.
Convert integers, floating-point values and enum types to enum types.
It can also cast pointers to or from integer types. The format in which this integer value
represents a pointer is platform-specific. The only guarantee is that a pointer cast to an
integer type large enough to fully contain it (such as intptr_t), is guaranteed to be able to
be cast back to a valid pointer.
The conversions that can be performed by reinterpret_cast but not by static_cast are low-
level operations based on reinterpreting the binary representations of the types, which
on most cases results in code which is system-specific, and thus non-portable. For
example:
class A { /* ... */ };
we dont take any liability for the notes correctness. http://www.rgpvonline.com
15
class B { /* ... */ };
A * a = new A;
B * b = reinterpret_cast<B*>(a);
This code compiles, although it does not make much sense, since now b points to an
object of a totally unrelated and likely incompatible class. Dereferencing b is unsafe.
const_cast
This type of casting manipulates the constness of the object pointed by a pointer, either
to be set or to be removed. For example, in order to pass a const pointer to a function
that expects a non-const argument:
// const_cast
#include <iostream>
using namespace std;
int main () {
const char * c = "sample text";
print ( const_cast<char *> (c) );
return 0;
}
The example above is guaranteed to work because function print does not write to the
pointed object. Note though, that removing the constness of a pointed object to actually
write to it causes undefined behavior.
typeid
typeid allows to check the type of an expression:
typeid (expression)
This operator returns a reference to a constant object of type type_info that is defined in
the standard header <typeinfo>. A value returned by typeid can be compared with
another value returned by typeid using operators == and != or can serve to obtain a null-
terminated character sequence representing the data type or class name by using its
name() member.
// typeid
#include <iostream>
#include <typeinfo>
using namespace std;
a and b are of different types:
int main () {
a is: int *
int * a,b;
b is: int
a=0; b=0;
if (typeid(a) != typeid(b))
{
cout << "a and b are of different types:\n";
cout << "a is: " << typeid(a).name() << '\n';
we dont take any liability for the notes correctness. http://www.rgpvonline.com
16
Notice how the type that typeid considers for pointers is the pointer type itself (both a
and b are of type class Base *). However, when typeid is applied to objects (like *a and
*b) typeid yields their dynamic type (i.e. the type of their most derived complete object).
If the type typeid evaluates is a pointer preceded by the dereference operator (*), and
this pointer has a null value, typeid throws a bad_typeid exception.
Unit-2/Lecture-5
The prevalence of programming languages such as Java, C++, Object Pascal, C#, and
Visual Basic make it incredibly clear that object-oriented technology has become the
approach of choice for new development projects. Although procedural languages such
as COBOL and PL/1 will likely be with us for decades it is clear that most organizations
now consider these environments as legacy technologies that must be maintained and
ideally retired at some point. Progress marches on.
My experience is that agile software developers, be they application developers or Agile
DBAs, must minimally have an understanding of object orientation if they are to be
effective. This includes understanding basic concepts such as inheritance,
polymorphism, and object persistence. Furthermore, all developers should have a basic
understanding of the industry-standard Unified Modeling Language (UML). A good
starting point is to understand what I consider to be the core UML diagrams – use case
diagrams, sequence diagrams, and class diagrams – although as I argued in An
Introduction to Agile Modeling and Agile Documentation you must be willing to learn
more models over time. One of the advantages of working closely with other IT
professionals is that you learn new skills from them, and the most effective object
developers will learn and adapt fundamental concepts from other disciplines. An
example is class normalization, the object-oriented version of data normalization, a
collection of simple rules for reducing coupling and increasing cohesion within your
object designs.
This article overviews the fundamental concepts and techniques that application
developers use on a daily basis when working with object technology. This article is
aimed at Agile DBAs that want to gain a basic understanding of the object paradigm,
allowing them to understand where application developers are coming from. The
primary goal of this article is to provide Agile DBAs with enough of an understanding of
objects so that they have a basis from which to communicate with application
developers. Similarly, other articles overview fundamental data concepts, such as
relational database technology and data modeling that application developers need to
learn so that they understand where Agile DBAs are coming from.
Object-Oriented Concepts
Agile software developers, including Agile DBAs, need to be familiar with the basic
concepts of object-orientation. The object-oriented (OO) paradigm is a development
strategy based on the concept that systems should be built from a collection of reusable
components called objects. Instead of separating data and functionality as is done in the
structured paradigm, objects encompass both. While the object-oriented paradigm
sounds similar to the structured paradigm, as you will see at this site it is actually quite
different. A common mistake that many experienced developers make is to assume that
they have been doing objects all along just because they have been applying similar
software-engineering principles. To succeed you must recognize that the OO approach is
different than the structured
To understand OO you need to understand common object terminology. The critical
terms to understand are summarized in Table 1. I present a much more detailed
we dont take any liability for the notes correctness. http://www.rgpvonline.com
18
explanation of these terms in The Object Primer 3/e. Some of these concepts you will
have seen before, and some of them you haven’t. Many OO concepts, such as
encapsulation, coupling, and cohesion come from software engineering. These concepts
are important because they underpin good OO design. The main point to be made here
is that you do not want to deceive yourself – just because you have seen some of these
concepts before, it don’t mean you were doing OO, it just means you were doing good
design. While good design is a big part of object-orientation, there is still a lot more to it
than that.
inheritance
A UML concept combining the data modeling concepts of cardinality
Multiplicity
(how many) and optionality.
Object A person, place, thing, event, concept, screen, or report
Main memory + all available storage space on the network, including
Object space
persistent storage such as a relational database
Something a class does (similar to a function in structured
Operation
programming)
Sometimes you need to override (redefine) attributes and/or methods
Override
in subclasses
A reusable solution to a common problem taking relevant forces into
Pattern
account
Persistence The issue of how objects are permanently stored
Persistent
An object that is saved to permanent storage
object
Different objects can respond to the same message in different ways,
Polymorphism enable objects to interact with one another without knowing their exact
type
Single
When a class directly inherits from only one class
inheritance
Stereotype Denotes a common usage of a modeling element
Subclass If class B inherits from class A, we say that B is a subclass of A
Superclass If class B inherits from class A, we say that A is a superclass of B
Transient object An object that is not saved to permanent storage
It is important for Agile DBAs to understand the terms presented above because the
application developers that you work with will use these terms, and many others, on a
regular basis. To communicate effectively with application developers you must
understand their vocabulary, and they must understand yours. Another important
aspect of learning the basics of object orientation is to understand each of the diagrams
of the Unified Modeling Language (UML) – you don’t need to become a UML expert, but
you do need to learn the basics.
an optional arrowhead on one end of the line indicating the direction of the initial
invocation of the relationship.
UNIT- 2/LECTURE- 6
we dont take any liability for the notes correctness. http://www.rgpvonline.com
21
}The malloc() function from C, still exists in C++, but it is recommended to avoid using
malloc() function. The main advantage of new over malloc() is that new doesn’t just
allocate memory, it constructs objects which is prime purpose of C++.
At any point, when you feel a variable that has been dynamically allocated is not anymore
required, you can free up the memory that it occupies in the free store with the delete
operator as follows:
delete pvalue; // Release memory pointed to by pvalueLet us put above concepts and
form the following example to show how new and delete work:
#include <iostream>
using namespace std;
int main ()
{
double* pvalue = NULL; // Pointer initialized with null
pvalue = new double; // Request memory for the variable
Return 0;
}
If we compile and run above code, this would produce the following result:
Value of pvalue : 29495
Dynamic Memory Allocation for Arrays:
Consider you want to allocate memory for an array of characters, i.e., string of 20
characters. Using the same syntax what we have used above we can allocate memory
dynamically as shown below.
Char* pvalue = NULL; // Pointer initialized with null
pvalue = new char[20]; // Request memory for the variable
To remove the array that we have just created the statement would look like this:
delete [] pvalue; // Delete array pointed to by pvalue
Following the similar generic syntax of new operator, you can llocate for a multi-
dimensional array as follows:
double** pvalue = NULL; // Pointer initialized with null
pvalue = new double [3][4]; // Allocate memory for a 3x4 array
However, the syntax to release the memory for multi-dimensional array will still remain
same as above:
delete [] pvalue; // Delete array pointed to by pvalue
Dynamic Memory Allocation for Objects:
Objects are no different from simple data types. For example, consider the following code
where we are going to use an array of objects to clarify the concept:
#include <iostream>
using namespace std;
class Box
{
public:
Box() {
cout << Constructor called! <<endl;
}
~Box() {
cout << Destructor called! <<endl;
}
};
int main( )
{
Box* myBoxArray = new Box[4];
we dont take any liability for the notes correctness. http://www.rgpvonline.com
23
return 0;
}
If you were to allocate an array of four Box objects, the Simple constructor would be
called four times and similarly while deleting these objects, destructor will also be called
same number of times.
If we compile and run above code, this would produce the following result:
Constructor called!
Constructor called!
Constructor called!
Constructor called!
Destructor called!
Destructor called!
Destructor called!
Destructor called!
UNIT- 2/LECTURE- 7
Template classes[RGPV/Dec,June2010(10)]
In the previous two lessons, you learn how function templates and function template
instances could be used to generalize functions to work with many different data types.
While this is a great start down the road to generalized programming, it doesn’t solve
all of our problems. Let’s take a look at an example of one such problem, and see what
templates can do for us further.
In the lesson on container classes, you learned how to use composition to implement
classes that contained multiple instances of other classes. As one example of such a
container, we took a look at the IntArray class. Here is a simplified example of that class:
#ifndef INTARRAY_H
#define INTARRAY_H
class IntArray
{
private:
int m_nLength;
int *m_pnData;
public:
IntArray()
{
m_nLength = 0;
m_pnData = 0;
}
IntArray(int nLength)
{
m_pnData = new int[nLength];
m_nLength = nLength;
}
~IntArray()
{
delete[] m_pnData;
}
void Erase()
{
delete[] m_pnData;
we dont take any liability for the notes correctness. http://www.rgpvonline.com
25
#endif
While this class provides an easy way to create arrays of integers, what if we want to
create an array of doubles? Using traditional programming methods, we’d have to
create an entirely new class! Here’s an example of DoubleArray, an array class used to
hold doubles.
#ifndef DOUBLEARRAY_H
#define DOUBLEARRAY_H
class DoubleArray
{
private:
int m_nLength;
double *m_pdData;
public:
DoubleArray()
{
m_nLength = 0;
m_pdData= 0;
}
DoubleArray(int nLength)
{
m_pdData= new double[nLength];
m_nLength = nLength;
}
~DoubleArray()
{
delete[] m_pdData;
}
we dont take any liability for the notes correctness. http://www.rgpvonline.com
26
void Erase()
{
delete[] m_pdData;
// We need to make sure we set m_pnData to 0 here, otherwise it will
// be left pointing at deallocated memory!
m_pdData= 0;
m_nLength = 0;
}
#endif
Although the code listings are lengthy, you’ll note the two classes are almost identical!
In fact, the only substantive difference is the contained data type. As you likely have
guessed, this is another area where templates can be put to good use to free us from
having to create classes that are bound to one specific data type.
Creating template classes is works pretty much identically to creating template functions,
so we’ll proceed by example. Here’s the IntArray classes, templatated version:
#ifndef ARRAY_H
#define ARRAY_H
public:
Array()
{
m_nLength = 0;
m_ptData = 0;
}
we dont take any liability for the notes correctness. http://www.rgpvonline.com
27
Array(int nLength)
{
m_ptData= new T[nLength];
m_nLength = nLength;
}
~Array()
{
delete[] m_ptData;
}
void Erase()
{
delete[] m_ptData;
// We need to make sure we set m_pnData to 0 here, otherwise it will
// be left pointing at deallocated memory!
m_ptData= 0;
m_nLength = 0;
}
#endif
As you can see, this version is almost identical to the IntArray version, except we’ve
added the template declaration, and changed the contained data type from int to T.
Note that we’ve also defined the GetLength() function outside of the class declaration.
This isn’t necessary, but new programmers typically stumble when trying to do this for
the first time due to the syntax, so an example is instructive. Each templated member
function declared outside the class declaration needs its own template declaration. Also,
note that the name of the templated array class is Array<T>, not Array — Array would
refer to a non-templated version of a class named Array.
int main()
we dont take any liability for the notes correctness. http://www.rgpvonline.com
28
{
Array<int> anArray(12);
Array<double> adArray(12);
return 0;
}
11 11.5
10 10.5
9 9.5
8 8.5
7 7.5
6 6.5
5 5.5
4 4.5
3 3.5
2 2.5
1 1.5
0 0.5
Templated classes are instanced in the same way templated functions are — the compile
stencils a copy upon demand with the template parameter replaced by the actual data
type the user needs and then compiles the copy. If you don’t ever use a template class,
the compile won’t even compile it.
Template classes are ideal for implementing container classes, because it is highly
desirable to have containers work across a wide variety of data types, and templates
allow you to do so without duplicating code. Although the syntax is ugly, and the error
messages can be cryptic, template classes are truly one of C++’s best and most useful
features.
Some older compilers (eg. Visual Studio 6) have a bug where the definition of template
class functions must be put in the same file as the template class is defined in. Thus, if
the template class were defined in X.h, the function definitions would have to also go in
X.h (not X.cpp). This issue should be fixed in most/all modern compilers.
UNIT -2/LECTURE -8
C++ Tutorials
In object-oriented programming languages like C++, the data and functions (procedures
to manipulate the data) are bundled together as a self-contained unit called an object. A
class is an extended concept similar to that of structure in C programming language; this
class describes the data properties alone. In C++ programming language, class describes
both the properties (data) and behaviors (functions) of objects. Classes are not objects,
but they are used to instantiate objects.
Features of Class:
Classes contain data known as members and member functions. As a unit, the collection
of members and member functions is an object. Therefore, this unit of objects makes up
a class.
Access specifiers:
Access specifiers are used to identify access rights for the data and member functions of
the class. There are three main types of access specifiers in C++ programming language:
private
public
protected
A private member within a class denotes that only members of the same class
have accessibility. The private member is inaccessible from outside the class.
Public members are accessible from outside the class.
A protected access specifier is a stage between private and public access. If
member functions defined in a class are protected, they cannot be accessed from outside
the class but can be accessed from the derived class.
When defining access specifiers, the programmer must use the keywords: private, public
or protected when needed, followed by a semicolon and then define the data and
member functions under it.
1. class exforsys
2. {
3. private:
4. int x,y;
5. public:
6. void sum()
we dont take any liability for the notes correctness. http://www.rgpvonline.com
31
7. {
8. & #46;...
9. & #46;...
10. }
11. };
In the code above, the member x and y are defined as private access. The member
function sum is defined as a public access.
Creation of Objects:
Once the class is created, one or more objects can be created from the class as objects
are instance of the class.
Just as we declare a variable of data type int as:
int x;
Objects are also declared as:
class_name followed_by object_name;
Example:
exforsys e1;
This declares e1 to be an object of class exforsys.
For example a complete class and object declaration is given below:
1. class exforsys
we dont take any liability for the notes correctness. http://www.rgpvonline.com
32
2. {
3. private:
4. int x,y;
5. public:
6. void sum()
7. {
8. & #46;...
9. & #46;...
10. }
11. };
12.
13. void main()
14. {
15. exforsys e1;
16. & #46;...
17. & #46;...
18. }
<="" p="">
For example:
1. class exforsys
2. {
3. private:
4. int x,y;
5. public:
6. void sum()
7. {
8. & #46;...
9. & #46;...
10. }
11. }e1;
Unit-2/ Lecture- 9
Language Concepts
The 5 Basic Concepts of Object Oriented Design are the implementation level features that are built
the programming language. These features are often referred to by these common names:
Encapsulation-A tight coupling or association of data structures with the methods or functions that
on the data. This is called a class, or object (an object is often the implementation of a class).
Data Protection -The ability to protect some components of the object from external entities. This
realized by language keywords to enable a variable to be declared as private or protected to the ownin
class.
Inheritance -The ability for a class to extend or override functionality of another class. The so called c
class has a whole section that is the parent class and then it has it's own set of functions and data.
Interface -A definition of functions or methods, and their signatures that are available for use
manipulate a given instance of an object.
Polymorphism -The ability to define different functions or classes as having the same name but takin
different data types.
Programming Concepts
There are several concepts that were derived from the new languages once they became popular.
new standards that came around pushed on three major things:
Re-usability-The ability to reuse code for multiple applications. If a programmer has already written
power function, then it should be written that any program can make a call to that function and it sho
work exactly the same.
Privacy -This is important for large programs and preventing loss of data.
Documentation -The commenting of a program in mark up that will not be converted to machine co
This mark up can be as long as the programmer wants, and allows for comprehensive information to
passed on to new programmers. This is important for both the re-usability and the maintainability
programs.