8.1 Classes Basics
Classes are an expanded concept of data structures: like data structures, they can contain data members, but they can also contain functions as members.
An object is an instantiation of a class. In terms of variables, a class would be the type, and an object would be the variable.
Classes are defined using either keyword class or keyword struct, with the following syntax:
class class_name {
access_specifier_1:
member1;
access_specifier_2:
member2;
...
} object_names;
Where class_name is a valid identifier for the class, object_names is an optional list of names for objects of this class. The body of the declaration can contain members, which can either be data or function declarations, and optionally access specifiers.
Classes have the same format as plain data structures, except that they can also include functions and have these new things called access specifiers. An access specifier is one of the following three keywords: private, public or protected. These specifiers modify the access rights for the members that follow them:
private members of a class are accessible only from within other members of the same class (or from their "friends").
protected members are accessible from other members of the same class (or from their "friends"), but also from members of their derived classes.
Finally, public members are accessible from anywhere where the object is visible.
By default, all members of a class declared with the class keyword have private access for all its members. Therefore, any member that is declared before any other access specifier has private access automatically.
Defining C++ Objects
A class provides the blueprints for objects, so basically an object is created from a class. We declare objects of a class with exactly the same sort of declaration that we declare variables of basic types. Following statements declare two objects of class Box:
Box Box1;
// Declare Box1 of type Box
Box Box2;
// Declare Box2 of type Box
Both of the objects Box1 and Box2 will have their own copy of data members.
8.2 Constructor - Destructor
Constructor
A constructor is a special kind of class member function that is executed when an object of that class is instantiated.
Constructors are typically used to initialize member variables of the class to appropriate default values, or to allow the user to easily initialize those member variables to whatever values are desired.
Unlike normal functions, constructors have specific rules for how they must be named:
1) Constructors should always have the same name as the class (with the same capitalization)
2) Constructors have no return type (not even void)
A constructor that takes no parameters (or has all optional parameters) is called a default constructor but if you need, a constructor can have parameters. This helps you to assign initial value to an object at the time of its creation.
Destructor
A destructor is another special kind of class member function that is executed when an object of that class is destroyed. They are the counterpart to constructors. When a variable goes out of scope, or a dynamically allocated variable is explicitly deleted using the delete keyword, the class destructor is called (if it exists) to help clean up the class before it is removed from memory.
For simple classes, a destructor is not needed because C++ will automatically clean up the memory for you. However, if you have dynamically allocated memory, or if you need to do some kind of maintenance before the class is destroyed (eg. closing a file), the destructor is the perfect place to do so.
Like constructors, destructors have specific naming rules:
1) The destructor must have the same name as the class, preceded by a tilde (~).
2) The destructor can not take arguments.
3) The destructor has no return type.
Note that rule 2 implies that only one destructor may exist per class, as there is no way to overload destructors since they can not be differentiated from each other based on arguments.
Example
class abc
{
private :
int a,b;
public :
abc()//default constructor
{
a=0;
b=1;
}
abc(int x, int y) //Parametrized constructor
{
a=x;
b=y;
}
~abc(); //destructor
.
.
.
};
8.3 Friend Function
A friend function of a class is defined outside that class' scope but it has the right to access all private and protected members of the class. Even though the prototypes for friend functions appear in the class definition, friends are not member functions.
A friend can be a function, function template, or member function, or a class or class template, in which case the entire class and all of its members are friends.
To declare a function as a friend of a class, precede the function prototype in the class definition with keyword friend as follows:
class ABC
{
double a;
public:
double b;
friend void printWidth( ABC abc );
void setWidth( double c );
};
To declare all member functions of class XYZ as friends of class ABC, place a following declaration in the definition of class ABC:
friend class XYZ;
8.4 Inheritance
Inheritance is one of the key feature of object-oriented programming including C++ which allows user to create a new class(derived class) from a existing class(base class). The derived class inherits all feature from a base class and it can have additional features of its own.
Inheritance makes the code reusable. When we inherit an existing class, all its methods and fields become available in the new class, hence code is reused.
Note that All members of a class except Private, are inherited.
Purpose of Inheritance
- Code Re usability
- Method Overriding (Hence, Runtime Polymorphism.)
- Use of Virtual Keyword
Basic Syntax of Inheritance
class Subclass_name : access_mode Superclass_name
While defining a subclass like this, the super class must be already defined or at least declared before the subclass declaration.
Access Mode is used to specify, the mode in which the properties of superclass will be inherited into subclass, public, private or protected.
Access Control and Inheritance
A derived class can access all the non-private members of its base class. Thus base-class members that should not be accessible to the member functions of derived classes should be declared private in the base class.
Access
1. same class can access all (public, private, protected) members.
2. derived class can access only public and protected members.
3. Outside classes can access only public members.
A derived class inherits all base class methods with the following exceptions:
- Constructors, destructors and copy constructors of the base class.
- Overloaded operators of the base class.
- The friend functions of the base class.
Inheritance Visibility Mode
Depending on Access modifier used while inheritance, the availability of class members of Super class in the sub class changes. It can either be private, protected or public.
1) Public Inheritance
This is the most used inheritance mode. In this the protected member of super class becomes protected members of sub class and public becomes public.
class Subclass : public Superclass
2) Private Inheritance
In private mode, the protected and public members of super class become private members of derived class.
class Subclass : Superclass
// By default its private inheritance
3) Protected Inheritance
In protected mode, the public and protected members of Super class becomes protected members of Sub class.
class subclass : protected Superclass
8.5 Function overloading
You can have multiple definitions for the same function name in the same scope. The definition of the function must differ from each other by the types and/or the number of arguments in the argument list. You can not overload function declarations that differ only by return type.
// overloading functions
#include <iostream.h>
using namespace std;
int add (int a, int b)
{
return (a+b);
}
double add (double a, double b)
{
return (a+b);
}
int main ()
{
int x=5,y=2;
double n=5.0,m=2.5;
cout << add(x,y) << '\n';
cout << add(n,m) << '\n';
return 0;
}
o/p:
7
7.5
In this example, there are two functions called add, but one of them has two parameters of type int, while the other has them of type double. The compiler knows which one to call in each case by examining the types passed as arguments when the function is called. If it is called with two int arguments, it calls to the function that has two int parameters, and if it is called with two doubles, it calls the one with two doubles.
Note that a function cannot be overloaded only by its return type. At least one of its parameters must have a different type.
8.6 Operator Overloading
Operator overloading is an important concept in C++. It is a type of polymorphism in which an operator is overloaded to give user defined meaning to it. Overloaded operator is used to perform operation on user-defined data type.
Overloaded operators are functions with special names the keyword operator followed by the symbol for the operator being defined. Like any other function, an overloaded operator has a return type and a parameter list.
Almost any operator can be overloaded in C++. However there are few operator which can not be overloaded. Operator that are not overloaded are follows
- scope operator - ::
- sizeof
- member selector - .
- member pointer selector - *
- ternary operator - ?:
Syntax
Return_type class_name :: operator operator_symbol(argument_list)
{
//function body
}
here operator is keyword and operator_symbol is operator to be overloaded.
Implementing Operator Overloading
Operator overloading can be done by implementing a function which can be :
Member Function
Non-Member Function
Friend Function
Operator overloading function can be a member function if the Left operand is an Object of that class, but if the Left operand is different, then Operator overloading function must be a non-member function.
Operator overloading function can be made friend function if it needs access to the private and protected members of class.
Restrictions on Operator Overloading
Following are some restrictions to be kept in mind while implementing operator overloading.
- Precedence and Associativity of an operator cannot be changed.
- Arity (numbers of Operands) cannot be changed. Unary operator remains unary, binary remains binary etc.
- No new operators can be created, only existing operators can be overloaded.
- Cannot redefine the meaning of a procedure. You cannot change how integers are added.
8.7 Polymorphism & virtual function
Polymorphism
"Poly" means "many" and "morph" means "form". Polymorphism is the ability of an object (or reference) to assume (be replaced by) or become many different forms of object. Typically, polymorphism occurs when there is a hierarchy of classes and they are related by inheritance.
C++ polymorphism means that a call to a member function will cause a different function to be executed depending on the type of object that invokes the function. Example: function overloading, virtual functions. Another example can be a plus + sign, used for adding two integers or for using it to concatenate two strings.
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;
}
// pure virtual function
virtual int area() = 0;
};
Important Points to Remember
1. Only the Base class Method's declaration needs the Virtual Keyword, not the definition.
2. If a function is declared as virtual in the base class, it will be virtual in all its derived classes.
3. The address of the virtual Function is placed in the VTABLE and the copiler uses VPTR(vpointer) to point to the Virtual Function.
8.8 Data Abstraction
Object Oriented Programming has a special feature called data abstraction. Data abstraction allows ignoring the details of how a data type is represented. While defining a class, both member data and member functions are described. However while using an object (that is an instance of a class) the built in data types and the members in the class are ignored. This is known as data abstraction. This can be seen from the above example.
Benefits of Data Abstraction
- 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 are public, then any function that directly accesses the data members of the old representation might be broken.
Example
#include <iostream.h>
#include <conio.h>
class base{
private: int s1,s2;
public: void inp_val()
{
cout <<"input the values of s1 and s2 ";
cin>>sl>>s2;
}
void display()
{
cout <<s1 <<" "<<s2<<"\n ";
}
};
void main(){
base b;
b.inp_val();
b.display();
}
Above class takes numbers from user, and returns both. The public members inp_val and display are the interfaces to the outside world and a user needs to know them to use the class. The private members s1 & s2 are something that the user doesn't need to know about, but is needed for the class to operate properly.
8.9 Data Encapsulation
Encapsulation is the method of combining the data and functions inside a class. This hides the data from being accessed from outside a class directly, only through the functions inside the class is able to access the information.
This is also known as "Data Abstraction", as it gives a clear separation between properties of data type and the associated implementation details. There are two types, they are "function abstraction" and "data abstraction". Functions that can be used without knowing how its implemented is function abstraction. Data abstraction is using data without knowing how the data is stored.
C++ supports the properties of encapsulation and data hiding through the creation of user-defined types, called classes. We know that class can have private, protected and public members. By default, all items defined in a class are private. For example: class add { public: double getadd(void) { return no1 + no2; } private: double no1; double no2; }; The variables no1 & no2 are private. This means that they can be accessed only by other members of the add 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.


Comments
Post a Comment