Smart Pointers

Smart Pointers - What, Why, Which?

What are they?

Smart pointers are objects that look and feel like pointers, but are smarter. What does this mean?

To look and feel like pointers, smart pointers need to have the same interface that pointers do: they need to support pointer operations like dereferencing (operator *) and indirection (operator ->). An object that looks and feels like something else is called a proxy object, or just proxy. The proxy pattern and its many uses are described in the books Design Patterns and Pattern Oriented Software Architecture.

To be smarter than regular pointers, smart pointers need to do things that regular pointers don't. What could these things be? Probably the most common bugs in C++ (and C) are related to pointers and memory management: dangling pointers, memory leaks, allocation failures and other joys. Having a smart pointer take care of these things can save a lot of aspirin...

The simplest example of a smart pointer is auto_ptr, which is included in the standard C++ library. You can find it in the header , or take a look at Scott Meyers' auto_ptr implementation. Here is part of auto_ptr's implementation, to illustrate what it does:

template <class T> class auto_ptr {     T* ptr; public:     explicit auto_ptr(T* p = 0) : ptr(p) {}     ~auto_ptr()                 {delete ptr;}     T& operator*()              {return *ptr;}     T* operator->()             {return ptr;}     // ... };
As you can see, auto_ptr is a simple wrapper around a regular pointer. It forwards all meaningful operations to this pointer (dereferencing and indirection). Its smartness in the destructor: the destructor takes care of deleting the pointer.

For the user of auto_ptr, this means that instead of writing:

void foo() {     MyClass* p(new MyClass);     p->DoSomething();     delete p; }
You can write:
void foo() {     auto_ptr<MyClass> p(new MyClass);     p->DoSomething(); }
And trust p to cleanup after itself.

What does this buy you? See the next section.

Why would I use them?

Obviously, different smart pointers offer different reasons for use. Here are some common reasons for using smart pointers in C++.

Why: Less bugs

Automatic cleanup. As the code above illustrates, using smart pointers that clean after themselves can save a few lines of code. The importance here is not so much in the keystrokes saved, but in reducing the probability for bugs: you don't need to remember to free the pointer, and so there is no chance you will forget about it.

Automatic initialization. Another nice thing is that you don't need to initialize the auto_ptr to NULL, since the default constructor does that for you. This is one less thing for the programmer to forget.

Dangling pointers. A common pitfall of regular pointers is the dangling pointer: a pointer that points to an object that is already deleted. The following code illustrates this situation:

MyClass* p(new MyClass); MyClass* q = p; delete p; p->DoSomething();   // Watch out! p is now dangling! p = NULL;           // p is no longer dangling q->DoSomething();   // Ouch! q is still dangling!
For auto_ptr, this is solved by setting its pointer to NULL when it is copied:
template <class T> auto_ptr& auto_ptr::operator=(auto_ptr& rhs) {     if (this != &rhs) {         delete ptr;         ptr = rhs.ptr;         rhs.ptr = NULL;     }     return *this; }
Other smart pointers may do other things when they are copied. Here are some possible strategies for handling the statement q = p, where p and q are smart pointers:
  • Create a new copy of the object pointed by p, and have q point to this copy. This strategy is implemented in copied_ptr.h.
  • Ownership transfer: Let both p and q point to the same object, but transfer the responsibility for cleaning up ("ownership") from p to q. This strategy is implemented in owned_ptr.h.
  • Reference counting: Maintain a count of the smart pointers that point to the same object, and delete the object when this count becomes zero. So the statement q = p causes the count of the object pointed by p to increase by one. This strategy is implemented in counted_ptr.h. Scott Meyers offers another reference counting implementation in his book More Effective C++.
  • Reference linking: The same as reference counting, only instead of a count, maintain a circular doubly linked list of all smart pointers that point to the same object. This strategy is implemented in linked_ptr.h.
  • Copy on write: Use reference counting or linking as long as the pointed object is not modified. When it is about to be modified, copy it and modify the copy. This strategy is implemented in cow_ptr.h.
All these techniques help in the battle against dangling pointers. Each has each own benefits and liabilities. The Which section of this article discusses the suitability of different smart pointers for various situations.

Why: Exception Safety

Let's take another look at this simple example:
void foo() {     MyClass* p(new MyClass);     p->DoSomething();     delete p; }
What happens if DoSomething() throws an exception? All the lines after it will not get executed and p will never get deleted! If we're lucky, this leads only to memory leaks. However, MyClass may free some other resources in its destructor (file handles, threads, transactions, COM references, mutexes) and so not calling it my cause severe resource locks.

If we use a smart pointer, however, p will be cleaned up whenever it gets out of scope, whether it was during the normal path of execution or during the stack unwinding caused by throwing an exception.

But isn't it possible to write exception safe code with regular pointers? Sure, but it is so painful that I doubt anyone actually does this when there is an alternative. Here is what you would do in this simple case:

void foo() {     MyClass* p;     try {         p = new MyClass;         p->DoSomething();         delete p;     }     catch (...) {         delete p;         throw;     } }
Now imagine what would happen if we had some if's and for's in there...

Why: Garbage collection

Since C++ does not provide automatic garbage collection like some other languages, smart pointers can be used for that purpose. The simplest garbage collection scheme is reference counting or reference linking, but it is quite possible to implement more sophisticated garbage collection schemes with smart pointers. For more information see the garbage collection FAQ.

Why: Efficiency

Smart pointers can be used to make more efficient use of available memory and to shorten allocation and deallocation time.

A common strategy for using memory more efficiently is copy on write (COW). This means that the same object is shared by many COW pointers as long as it is only read and not modified. When some part of the program tries to modify the object ("write"), the COW pointer creates a new copy of the object and modifies this copy instead of the original object. The standard string class is commonly implemented using COW semantics (see the header).

string s("Hello");  string t = s;       // t and s point to the same buffer of characters  t += " there!";     // a new buffer is allocated for t before                     // appending " there!", so s is unchanged.

Optimized allocation schemes are possible when you can make some assumptions about the objects to be allocated or the operating environment. For example, you may know that all the objects will have the same size, or that they will all live in a single thread. Although it is possible to implement optimized allocation schemes using class-specific new and delete operators, smart pointers give you the freedom to choose whether to use the optimized scheme for each object, instead of having the scheme set for all objects of a class. It is therefore possible to match the allocation scheme to different operating environments and applications, without modifying the code for the entire class.

Why: STL containers

The C++ standard library includes a set of containers and algorithms known as the standard template library (STL). STL is designed to be generic (can be used with any kind of object) and efficient (does not incur time overhead compared to alternatives). To achieve these two design goals, STL containers store their objects by value. This means that if you have an STL container that stores objects of class Base, it cannot store of objects of classes derived from Base.
class Base { /*...*/ }; class Derived : public Base { /*...*/ };  Base b; Derived d; vector<Base> v;  v.push_back(b); // OK v.push_back(d); // error
What can you do if you need a collection of objects from different classes? The simplest solution is to have a collection of pointers:
vector<Base*> v;  v.push_back(new Base);      // OK v.push_back(new Derived);   // OK too  // cleanup: for (vector<Base*>::iterator i = v.begin(); i != v.end(); ++i)     delete *i;
The problem with this solution is that after you're done with the container, you need to manually cleanup the objects stored in it. This is both error prone and not exception safe.

Smart pointers are a possible solution, as illustrated below. (An alternative solution is a smart container, like the one implemented in pointainer.h.)

vector< linked_ptr<Base> > v; v.push_back(new Base);      // OK v.push_back(new Derived);   // OK too  // cleanup is automatic
Since the smart pointer automatically cleans up after itself, there is no need to manually delete the pointed objects.

Note: STL containers may copy and delete their elements behind the scenes (for example, when they resize themselves). Therefore, all copies of an element must be equivalent, or the wrong copy may be the one to survive all this copying and deleting. This means that some smart pointers cannot be used within STL containers, specifically the standard auto_ptr and any ownership-transferring pointer. For more info about this issue, see C++ Guru of the Week #25.

Which one should I use?

Are you confused enough? Well, this summary should help.

Which: Local variables

The standard auto_ptr is the simplest smart pointer, and it is also, well, standard. If there are no special requirements, you should use it. For local variables, it is usually the right choice.

Which: Class members

Although you can use auto_ptr as a class member (and save yourself the trouble of freeing objects in the destructor), copying one object to another will nullify the pointer, as illustrated Below.
class MyClass {     auto_ptr<int> p;     // ... };  MyClass x; // do some meaningful things with x MyClass y = x; // x.p now has a NULL pointer
Using a copied pointer instead of auto_ptr solves this problem: the copied object (y) gets a new copy of the member.

Note that using a reference counted or reference linked pointer means that if y changes the member, this change will also affect x! Therefore, if you want to save memory, you should use a COW pointer and not a simple reference counted/linked pointer.

Which: STL containers

As explained above, using garbage-collected pointers with STL containers lets you store objects from different classes in the same container.

It is important to consider the characteristics of the specific garbage collection scheme used. Specifically, reference counting/linking can leak in the case of circular references (i.e., when the pointed object itself contains a counted pointer, which points to an object that contains the original counted pointer). Its advantage over other schemes is that it is both simple to implement and deterministic. The deterministic behavior may be important in some real time systems, where you cannot allow the system to suddenly wait while the garbage collector performs its housekeeping duties.

Generally speaking, there are two ways to implement reference counting: intrusive and non-intrusive. Intrusive means that the pointed object itself contains the count. Therefore, you cannot use intrusive reference counting with 3-rd party classes that do not already have this feature. You can, however, derive a new class from the 3-rd party class and add the count to it. Non-intrusive reference counting requires an allocation of a count for each counted object. The counted_ptr.h is an example of non-intrusive reference counting.

Intrusive reference counting Non-intrusive reference counting
Reference linking does not require any changes to be made to the pointed objects, nor does it require any additional allocations. A reference linked pointer takes a little more space than a reference counted pointer - just enough to store one or two more pointers. Reference linking

Both reference counting and reference linking require using locks if the pointers are used by more than one thread of execution.

Which: Explicit ownership transfer

Sometimes, you want to receive a pointer as a function argument, but keep the ownership of this pointer (i.e. the control over its lifetime) to yourself. One way to do this is to use consistent naming-conventions for such cases. Taligent's Guide to Designing Programs recommends using "adopt" to mark that a function adopts ownership of a pointer.

Using an owned pointer as the function argument is an explicit statement that the function is taking ownership of the pointer.

Which: Big objects

If you have objects that take a lot of space, you can save some of this space by using COW pointers. This way, an object will be copied only when necessary, and shared otherwise. The sharing is implemented using some garbage collection scheme, like reference counting or linking.

Which: Summary

For this: Use that:
Local variables auto_ptr
Class members Copied pointer
STL Containers Garbage collected pointer (e.g. reference counting/linking)
Explicit ownership transfer Owned pointer
Big objects Copy on write

Conclusion

Smart pointers are useful tools for writing safe and efficient code in C++. Like any tool, they should be used with appropriate care, thought and knowledge. For a comprehensive and in depth analysis of the issues concerning smart pointers, I recommend reading Andrei Alexandrescu's chapter about smart pointers in his book Modern C++ Design.

Feel free to use my own smart pointers in your code, and do tell me if you are having any problems with them.
The Boost C++ libraries include some smart pointers, which are more rigorously tested and actively maintained. Do try them first, if they are appropriate for your needs.

Basic C++ Interview Questions And Answers


1. What is virtual constructors/destructors?
Virtual destructors: If an object (with a non-virtual destructor) is destroyed explicitly by applying the delete operator to a base-class pointer to the object, the base-class destructor function (matching the pointer type) is called on the object.
There is a simple solution to this problem – declare a virtual base-class destructor. This makes all derived-class destructors virtual even though they don’t have the same name as the base-class destructor. Now, if the object in the hierarchy is destroyed explicitly by applying the delete operator to a base-class pointer to a derived-class object, the destructor for the appropriate class is called.

Virtual constructor: Constructors cannot be virtual. Declaring a constructor as a virtual function is a syntax error. Does c++ support multilevel and multiple inheritance?
Yes.

What are the advantages of inheritance?
• It permits code reusability.
• Reusability saves time in program development.
• It encourages the reuse of proven and debugged high-quality software, thus reducing problem
after a system becomes functional.

What is the difference between declaration and definition?
The declaration tells the compiler that at some later point we plan to present the definition of this declaration.
E.g.: void stars () //function declaration
The definition contains the actual implementation.
E.g.: void stars () // declarator
{
for(int j=10; j>=0; j--) //function body
cout<<”*”; cout< function_declaration; template
function_declaration;
The only difference between both prototypes is the use of keyword class or typename, its use is
indistinct since both expressions have exactly the same meaning and behave exactly the same way.

6. What do you mean by inline function?
The idea behind inline functions is to insert the code of a called function at the point where the
function is called. If done carefully, this can improve the application's
performance in exchange for increased compile time and possibly (but not always) an increase in the size of the generated binary executables.

7. What is virtual class and friend class?
Friend classes are used when two or more classes are designed to work together and need access
to each other's implementation in ways that the rest of the world
shouldn't be allowed to have. In other words, they help keep private things private. For instance, it may be desirable for class DatabaseCursor to have more privilege to the internals of class Database than main() has.

8. What is function overloading and operator overloading?
Student Resources Function overloading: C++ enables several functions of the same name to be defined, as long as these functions have different sets of parameters (at least as far as their types are concerned). This capability is called function overloading. When an overloaded function is called, the C++ compiler selects the proper function by examining the number, types and order of the arguments in the call.
Function overloading is commonly used to create several functions of the same name that perform similar tasks but on different data types.
Operator overloading allows existing C++ operators to be redefined so that they work on objects
of user-defined classes. Overloaded operators are syntactic sugar for
equivalent function calls. They form a pleasant facade that doesn't add anything fundamental to the language (but they can improve understandability and reduce
maintenance costs).

9. Difference between realloc() and free()?
The free subroutine frees a block of memory previously allocated by the malloc subroutine.
Undefined results occur if the Pointer parameter is not a valid pointer. If the Pointer parameter is a null value, no action will occur. The realloc subroutine changes the size of the block of memory pointed to by the Pointer parameter to the number of bytes specified by the Size parameter and returns a new pointer to the block. The pointer specified by the Pointer parameter must have been created with the malloc, calloc, or realloc subroutines and not been deallocated with the free or realloc subroutines. Undefined results occur if the Pointer parameter is not a valid pointer

10. What do you mean by binding of data and functions?
Encapsulation.

11. What is abstraction?
Abstraction is of the process of hiding unwanted details from the user.
12. What is encapsulation?
Packaging an object’s variables within its methods is called encapsulation.
13. What is the difference between an object and a class?
Classes and objects are separate but related concepts. Every object belongs to a class and every
class contains one or more related objects.
Ø A Class is static. All of the attributes of a class are fixed before, during, and after the execution of a program. The attributes of a class don't change.
Ø The class to which an object belongs is also (usually) static. If a particular object belongs to a
certain class at the time that it is created then it almost certainly will still belong to that class right up until the time that it is destroyed.

Ø An Object on the other hand has a limited lifespan. Objects are created and eventually destroyed. Also during that lifetime, the attributes of the object may undergo significant change.

14. What is polymorphism? Explain with an example?
"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.
Example: function overloading, function overriding, virtual functions. Another example can be a plus ‘+’ sign, used for adding two integers or for using it to concatenate two strings.

15. What do you mean by inheritance?
Inheritance is the process of creating new classes, called derived classes, from existing classes or
base classes. The derived class inherits all the capabilities of the base class, but can add
embellishments and refinements of its own.
16. What is a scope resolution operator?
A scope resolution operator (::), can be used to define the member functions of a class outside the class.
17. What are virtual functions?
A virtual function allows derived classes to replace the implementation provided by the base class. The compiler makes sure the replacement is always called whenever
the object in question is actually of the derived class, even if the object is accessed by a base pointer rather than a derived pointer. This allows algorithms in the base class to be replaced in the derived class, even if users don't know about the derived class.

18. What is friend function?
As the name suggests, the function acts as a friend to a class. As a friend of a class, it can access its private and protected members. A friend function is not a member of
the class. But it must be listed in the class definition.

19. What is the difference between class and structure?
Structure: Initially (in C) a structure was used to bundle different type of data types together to
perform a particular functionality. But C++ extended the structure to contain functions also. The
major difference is that all declarations inside a structure are by default public.
Class: Class is a successor of Structure. By default all the members inside the class are private.

20. What is public, protected, private?
Ø Public, protected and private are three access specifiers in C++.
Ø Public data members and member functions are accessible outside the class.
Ø Protected data members and member functions are only available to derived classes.
Ø Private data members and member functions can’t be accessed outside the class.
However there is an exception can be using friend classes.

21. What is an object?
Object is a software bundle of variables and related methods. Objects have state and behavior.
22. What is a class?
Class is a user-defined data type in C++. It can be created to solve a particular kind of problem.
After creation the user need not know the specifics of the working of a class.

C++ Source code for Different C++ and OOPS Concepts

Exp.No: 1

IMPLEMENTATION OF CLASS

AIM:

A program to solve a quadratic equation, using OOP techniques.

ALGORITHAM:

1) Start the process

2) Invoke the classes

3) Get the input for a,b,c;

4) Call the function getinfo() and display()

5) Check if a=0

a) True : compute c/b;

i) Print the value of a/c;

b) False: compute b*b-4*a*c;

i) If ( b*b-4*a*c)=0

ii) Call img();

iii) Otherwise : call real(a,b,c);

6) Stop the process

PROGRAM:

#include

#include

class equation

{

private:float a,b,c;

public: void getinfo(float a, float b,float c );

void display( );

void equal(float a, float b);

void imag( );

void real(float a,float b,float c);

};

void equation :: getinfo(float aa,float bb,float cc)

{

a=aa;

b=bb;

c=cc;

}

void equation::display( )

{

cout<

cout<<”a=”<<<’\t’;

cout<<”b=”<<<’\t’;

cout<<”c=”<<

}

void equation ::equal (float a,float b)

{

float x;

x = -b/(2*a);

cout<<”Roots are equal “<<

}

void equation :: imag( )

{

cout<<”Roots are imaginary”;

}

void equation :: real(float a,float b,float det)

{

float x1,x2,temp;

temp = sqrt(det);

x1= (-b + temp)/(2*a);

x2 = (-b –temp)/(2*a);

cout<<”Roots are real”;

cout<<”x1= “<<

cout<<”x2 =”<<

}

void main( )

{

class equation e;

float aa,bb,cc;

clrscr( );

cout<<”Enter the three numbers”;

cin>>aa>>bb>>cc;

e.getinfo(aa,bb,cc);

e.display( );

if(aa = =0)

{

float temp;

temp = cc/bb;

cout<<” Linear Roots”<<

}

else

{

float det;

det = (bb*bb – 4*aa*cc);

if(det = =0)

e.equal(aa,bb);

else if (det<0>

e.imag( );

else

e.real(aa,bb,cc );

}

getch( );

OUTPUT:

Enter the three numbers 2 4 1

Roots are imaginary

X1= - 0.292893

X2= - 1.707107

RESULT:


Exp.No: 2

CONSTRUCTOR AND DESTRUCTOR

AIM:

A program to print student details using constructor and destructor

ALGORITHAM:

1. Start the process

2. Invoke the classes

3. Call the read() function

a. Get the inputs name ,roll number and address

4. Call the display() function

a. Display the name,roll number,and address of the student

5. Stop the process

PROGRAM

#include

#include

class stu

{

private: char name[20],add[20];

int roll,zip;

public: stu ( );//Constructor

~stu( );//Destructor

void read( );

void disp( );

};

stu :: stu( )

{

cout<<”This is Student Details”<

}

void stu :: read( )

{

cout<<”Enter the student Name”;

cin>>name;

cout<<”Enter the student roll no “;

cin>>roll;

cout<<”Enter the student address”;

cin>>add;

cout<<”Enter the Zipcode”;

cin>>zip;

}

void stu :: disp( )

{

cout<<”Student Name :”<<

cout<<”Roll no is :”<<

cout<<”Address is :”<<

cout<<”Zipcode is :”<

}

stu : : ~stu( )

{

cout<<”Student Detail is Closed”;

}

void main( )

{

stu s;

clrscr( );

s.read ( );

s.disp ( );

getch( );

}




Output:

Enter the student Name

James

Enter the student roll no

01

Enter the student address

Newyork

Enter the Zipcode

919108

Student Name : James

Roll no is : 01

Address is : Newyork

Zipcode is :919108


RESULT:

Thus the program is executed and its output is verified.

Exp.No: 3

FRIEND FUNCTION

AIM:

A program to illustrate the use of dereferencing operators to access the class member

ALGORITHAM:

1) Start the process

2) Invoke the classes

3) Call the set_xy() first

a) Assign the value of x and y

b) Print the value of x and y

4) Call the sum() for second(friend)

a) Again assign the temp value of x and y

5) Print the value of x and y

6) Stop the process

PROGRAM

#include

class M

{

int x;

int y;

public:

void set_xy(int a,int b)

{

x=a;

y=b;

}

friend int sum(M m);

};

int sum(M m)

{

int M ::* px=&M :: x;

int M ::* py=&M :: y;

M *pm=&m;

int s=m.*px + pm->*py;

return s;

}

main()

{

M n;

void (M :: *pf)(int,int)=&M :: set_xy;

(n.*pf)(10,20);

cout<<"Sum="<<<"\n";

M *op=&n;

(op->*pf)(30,40);

cout<<"Sum="<<<"\n";

return(0);

}

Output:

Sum=30

Sum=70

RESULT:

Thus the program is executed and its output is verified.


Exp.No: 4

FUNCTION OVERLOADING

AIM:

A program to demonstrate how function overloading is carried out for swapping of two variables of the various data types, namely integer, floating point number and character types

ALGORITHAM:

· Start the process

· Get the integer values of ix,iy

· Get the floating values of fx,fy

· Get the character values of cx,cy

· Call swap(ix,iy)

o Assign temp<-a

o Assighn a<-b,b<-temp

· Swapping the integer values

· Print the value of ix and iy

· Swapping floating values

· Print the values oh fx and fy

· Swapping on characters

· Print the value of cx,cy

· Stop the process

PROGRAM

#include

#include

void swap(int &ix,int &iy);

void swap(float &fx,float &fy);

void swap(char &cx,char &cy);

void main()

{

int ix,iy;

float fx,fy;

char cx,cy;

clrscr();

cout<<"Enter 2 integers:";

cin>>ix>>iy;

cout<<"Enter 2 floating point no:s:";

cin>>fx>>fy;

cout<<"Enter 2 characters:";

cin>>cx>>cy;

cout<<"\nIntegers:";

cout<<"\nix="<<<"\niy="<

swap(ix,iy);

cout<<"\nAfter swapping";

cout<<"\nix="<<<"\niy="<

cout<<"\nFloating point no:s";

cout<<"\nfx="<<<"\nfy="<

swap(fx,fy);

cout<<"\nAfter swapping";

cout<<"\nfx="<<<"\nfy="<

cout<<"\nCharacters";

cout<<"\ncx="<<<"\ncy="<

swap(cx,cy);

cout<<"\nAfter swapping";

cout<<"\ncx="<<<"\ncy="<

getch();

}

void swap(int &a,int &b)

{

int temp;

temp=a;

a=b;

b=temp;

}

void swap(float &a, float &b)

{

float temp;

temp=a;

a=b;

b=temp;

}

void swap(char &a, char &b)

{

char temp;

temp=a;

a=b;

b=temp;

}

Output:

Enter 2 integers: 100 200

Enter 2 floating point no:s :-11.11 22.22

Enter 2 characters: s t

Integers:

Ix=100

Iy=200

After swapping

Ix=200

Iy=100

Floating point no:

Fx=-11.11

Fy=22.22

After swapping

Fx=22.22

Fy=-11.11

Characters

Cx=s

Cy=t

After swapping

Cx=t

Cx=s

RESULT:

Thus the program is executed and its output is verified.



Exp.No .5

UNARY OPERATOR

AIM:

A program for overloading the unary operator ++.

ALGORITHAM:

· Start the process

· Invoke the class counter

· Crate two objects c1 and c2

· Assign values to c1 an c2

o Call c1.get_count()

o Call c2.get_count()

· Increment the values

o C1++

o C2++

o ++c2

· Print c1 and c2

· Stop the process

PROGRAM

#include

#include

class counter

{

int count;

public:

counter()

{

count=0;

}

int get_count()

{

return count;

}

void operator++()

{

count++;

}

};

void main()

{

counter c1,c2;

cout<<"\nC1 ="<

cout<<"\nC2 ="<

c1++; //Using overloaded ++ operator.

c2++;

++c2;

cout<<"\nC1 ="<

cout<<"\nC2 ="<

getch();

}

OUT PUT:

C1=0 C2=O

C1=1 C2=2

RESULT:

Thus the program is executed and its output is verified.


Exp.No .6

BINARY OPERATOR

AIM:

A program to perform simple arithmetic operations of two complex numbers using operator overloading.

ALGORITHAM:

· Start the process

· Get the complex value a.real and a.image

· Check while ((ch=getchar())!=’q’)

o True : execute switch(ch)

o Case ‘a’:Then

Compute c<-a+b, Print c.real and c.imag

o Case ‘s’: Then

Compute c<-a-b, Print c.real and c.imag

o Case ‘m’: Then

Compute c<-a*b, Print c.real and c.imag

o Case ‘d’: Then

Compute c<-a/b, Print c.real and c.imag

o End of switch

· End of while

· Stop the process

PROGRAM

#include

#include

#include

struct complex

{

float real;

float imag;

};

complex operator + (complex a,complex b);

complex operator - (complex a,complex b);

complex operator * (complex a,complex b);

complex operator / (complex a,complex b);

void main()

{

complex a,b,c;

int ch;

void menu(void);clrscr();

cout<<"Enter the first complex no:";

cin>>a.real>>a.imag;

cout<<"Enter the second complex no:";

cin>>b.real>>b.imag;

menu();

while ((ch = getchar()) != 'q')

{

switch(ch)

{

case 'a':c =a + b;

cout<<"Addition of 2 no’s";

cout<<<"+i"<

break;

case 's':c=a-b;

cout<<"Substraction of 2 no’s";

cout<<<"i"<

break;

case 'm':c=a*b;

cout<<"Multiplication of 2 no’s";

cout<<<"i"<

break;

case 'd':c=a/b;

cout<<"Division of 2 no’s";

cout<<<"i"<

break;

}

}

}

void menu()

{

cout<<"complex no: operators";

cout<<"a->addition";

cout<<"s->substraction";

cout<<"m->multiplication";

cout<<"d->division";

cout<<"q->quit";

cout<<"options please";

}

complex operator -(struct complex a, struct complex b)

{

complex c;

c.real=a.real-b.real;

c.imag=a.imag-b.imag;

return(c);

}

complex operator *(struct complex a, struct complex b)

{

complex c;

c.real=((a.real*b.real)-(a.imag*b.imag));

c.imag=((a.real*b.imag)+(a.imag*b.real));

return(c);

}

complex operator +(struct complex a,struct complex b)

{

complex c;

c.real=a.real+b.real;

c.imag=a.imag+b.imag;

return(c);

}

complex operator /(struct complex a, struct complex b)

{

complex c;

float temp;

temp=((b.real*b.real)+(b.imag*b.imag));

c.real=((a.real*b.real)+(a.imag*b.imag))/temp;

return(c);

}

OUTPUT

Enter the first complex no: 1,1

Enter the second complex no: 2,2

Addition of 2 no’s : 3+I3


RESULT:

Thus the program is executed and its output is verified.


Exp.No .7

SINGLE INHERITANCE

AIM:

A program to illustrate a single inheritance. We have a base class B and a derived class D. The class B contains one private data member, one public data member and three public member functions. The class D contains one private data member and two public member functions

ALGORITHAM:

· Start the process

· Invoke the base class B

· Invoke the derived class D using public derivation

· Get the input data

· Display the inputted data

· Call the derived classes member functions

o Assign a new value for base classes data member

· Display the outputs

· Stop the process

PROGRAM

#include

#include

class B

{

int a;

public:

int b;

void get_ab();

int get_a();

void show_a();

};

class D: private B

{

int c;

public:

void mul();

void display();

};

void B::get_ab()

{

cout<<"Enter Values for a and b";

cin>>a>>b;

}

int B::get_a()

{

return a;

}

void B::show_a(){

cout<<"a= "<<<"\n";

}

void D::mul()

{

get_ab();

c=b*get_a();

}

void D:: display()

{

show_a();

cout<<"b= "<<<"\n";

cout<<"c= "<<<"\n\n";

}

void main()

{

clrscr();

D d;

d.mul();

d.display();

d.mul();

d.display();

getch();

}

OUTPUT

A=5

A=5

B=10

C=50

A=5

B=20

C=100


RESULT:

Thus the program is executed and its output is verified.


Exp.No .8

MULTILEVEL INHERITANCE

AIM:

A program to illustrate multilevel inheritance. we have three classes, student, test and result. Here class student is the base class. And the class test is derived from the base class student. And the another class result is derived from the class test.

ALGORITHAM:

· Start the process

· Invoke the base class student

· Invoke the derived class test which in inherited by the class student

· Invoke the derived class result which in inherited by the class test

· Create an object student1 for the result class

· Call student1.getno(),assign the value of rno in student class

· Call student1.getmarks(),assign the marks in test class

· Call student1.display(),for displaying the result

· Stop the process

PROGRAM

#include

#include

class student

{

protected:

int rno;

public:

void getno(int);

void putno(void);

};

void student::getno(int a)

{

rno=a;

}

void student ::putno()

{

cout<<"rollno="<<

}

class test:public student

{

protected:

float sub1;

float sub2;

public:

void getmarks(float,float);

void putmarks(void);

};

void test::getmarks(float x,float y)

{

sub1=x;

sub2=y;

}

void test::putmarks()

{

cout<<"marks in sub1="<<

cout<<"marks in sub2="<<

}

class result:public test

{

float total;

public:

void display(void);

};

void result::display(void)

{

total=sub1+sub2;

putno();

putmarks();

cout<<"total="<<

}

int main()

{

clrscr();

result student1;

student1.getno(111);

student1.getmarks(75.0,59.5);

student1.display();

getch();

return 0;

getch();

}

OUTPUT

Roll number:111

Marks in sub1=75

Marks in sub2=59.5

Total=134.5

RESULT:

Thus the program is executed and its output is verified.


Exp.No .9

MULTIPLE INHERITANCES

AIM:

` Write a program to illustrating how all the three classes are implemented in multiple inheritance mode

ALGORITHM

· Start the process

· Invoke the class M

· Invoke the another class N

· Invoke one more class,ie class P,which is inherited by both M and N

· Create an object for class p,ie P p

· Call p.get_m(),assign the value in to ‘m’

· Call p.get_n(),assign the value in to ‘n’

· Call display(), for dispay the result

· Stop the result

PROGRAM:

#include

#include

Class M

{

Protected:

Int m;

Public :

Void get_M();

};

Class N

{

Protected:

Int n;

Public:

Void get_N();

};

Class p: public M, public N

{

Public:

Void disply(void);

};

Void M ::get_m(int x)

{

m=x;

}

Void N::get_n(int y)

{

n=y;

}

Void P:: disply(void)

{

Cout<<”m=”<<

Cout<<”n=”<<

Cout<<”m*n=”<<

}

int main()

{

P p;

p.get_m(10);

p.get_n(20);

p.display();

return 0;

}

OUTPUT

m=10

n=20

m*n=200

RESULT:

Thus the program is executed and its output is verified.



Exp.No .10

HYBRID INHERITANCE

#include

#include

class stu

{

protected:

int rno;

public:

void get_no(int a)

{

rno=a;

}

void put_no(void)

{

out<<"Roll no"<<<"\n";

}

};

class test:public stu

{

protected:

float part1,part2;

public:

void get_mark(float x,float y)

{

part1=x;

part2=y;

}

void put_marks()

{

cout<<"Marks obtained:"<<"part1="<<<"\n"<<"part2="<<<"\n";

}

};

class sports

{

protected:

float score;

public:

void getscore(float s)

{

score=s;

}

void putscore(void)

{

cout<<"sports:"<<<"\n";

}

};

class result: public test, public sports

{

float total;

public:

void display(void);

};

void result::display(void)

{

total=part1+part2+score;

put_no();

put_marks();

putscore();

cout<<"Total Score="<<<"\n";

}

int main()

{

clrscr();

result stu;

stu.get_no(123);

stu.get_mark(27.5,33.0);

stu.getscore(6.0);

stu.display();

return 0;

}

OUTPUT

Roll no 123

Marks obtained : part1=27.5

Part2=33

Sports=6

Total score = 66.5

RESULT:

Thus the program is executed and its output is verified.


Exp.No .11

STATIC MEMBER FUNCTIONS

AIM

Write a program to illustrate the static member function.

ALGORITHM

1. Start the process

2. Invoke the class

i. Set the data member and member function as a static

b. Create two objects t1 and t2

3. Call the function t1.setcode

i. Increment the value of data member count

4. Call the function t1.setcode

i. Increment the value of data member count

5. Call the static member function showcount()

i. Display the value of count

6. Create a new object t3

7. Call the function t3.set code()

8. Call t1.showcount(), t2.showcount() and t3.showcount()

9. Stop the process

PROGRAM

#include

#include

class test

{

int code;

static int count;

public :

void setcode(void)

{

code= ++count;

}

void showcode(void)

{

cout<<"object number"<<

}

static void showcount(void)

{

cout<<"count"<<

}

};

int test::count;

int main()

{

clrscr();

test t1,t2;

t1.setcode();

t2.setcode();

test::showcount();

test t3;

t3.setcode();

test::showcount();

t1.showcode();

t2.showcode();

t3.showcode();

getch();

return(1);

}

OUTPUT

Count 2

Count 3

Object number 1

Object number 2

Object number 3


RESULT:

Thus the program is executed and its output is verified.


Exp.No .12

VIRTUAL FUNCTIONS

AIM

A program to access the member of the derived class objects through an array of members. In this program, both the base class and the derived class member functions are preceded by the keyword

ALGORITHM

1. Start the process

2. Invoke the class with pointer

3. Assign ptr[0] <- &objb;

i. Assign ptr[1] <- &objc;

4. Ptr(0)points the getdata()

a. Get the values of x and y

5. Ptr(1) points to the getdata()

a. Get the roll no and name of the student

6. Ptr(0) and ptr(1) are points to the display()

a. Print the values

7. Stop the process

PROGRAM

#include

#include

class base

{

private: int x;

float y;

public:

virtual void getdata( );

virtual void display( );

};

class devb: public base

{

private: int roll;

char name[20];

public: virtual void getdata( );

virtual void display( );

};

class devc : public base

{

private: float height;

float weight;

public : virtual void getdata( );

virtual void display( );

}:

void base :: getdata( )

{

cout<<” Enter any Integer”;

cin>>x;

cout<<”Enter a real no”;

cin>>y;

}

void base ::display( )

{

cout<<”The no X=”<<<”y=”<<

}

void devb :: display( )

{

cout<<”Roll of the Student is:”<<

cout<<” Name of the Student is: “<<

}

void devb :: getdata( )

{

cout<<”Enter the Roll of the Student:”;

cin>>roll;

cout<<”Enter Name of Student :”;

cin>>name;

}

void devc :: getdata( )

{

cout<<”Enter height and weight”;

cin>>height>>weight;

}

void devc :: display( )

{

cout<<”Height :”<<

cout<<”Weight :”<<

}

void main( )

{

base *ptr[3];

devb objb;

devc objc;

clrscr( );

ptr[0] = &objb;

ptr[1] = &objc;

ptr[0] ->getdata( );

ptr[1] -> getdata( );

ptr[1] -> display( );

ptr[1] -> display( );

getch ( );

}

OUTPUT

Enter the Roll of the Student: 101

Enter Name of Student : salah

height and weight 170 72

Roll of the Student is:101

Name of the Student is:salah

Height :170

Weight :72

RESULT:

Thus the program is executed and its output is verified.

Exp.No .13

PURE VIRTUAL FUNCTION

AIM

A program to demonstrate how a pure virtual function is defined, declared and invoked from the object of derived class through the pointer of the base class.

ALGORITHM

1. Start the process

2. Invoke the class with pointer

3. Assign ptr<-&obj

4. Call the ptr->getdata()

a. Get the roll no and name of the student

5. Call the ptr->display()

a. Print the roll no and name

6. Stop the process

PROGRAM

#include

#include

class base

{

private: int x;

float y;

public : virtual void getdata( );

virtual void display( );

};

class dev : public base

{

private: int roll;

char name[20];

public : void getdata( );

void display( );

};

void base :: getdata( ) { }

void base :: display( ) { }

void dev :: getdata( )

{

cout<<” Enter Roll of the Student “;

cin>> roll;

cout<<” Enter name of the student”;

cin>>name;

}

void dev :: display( )

{

cout<<”Name is :”<<

cout<<” Roll no is :”<

}

void main( )

{

base * ptr;

dev obj;

clrscr( );

ptr = &obj;

ptr -> getdata( );

ptr -> display( );

getch( );

}

OUTPUT

Enter the roll no of the student: 111

Enter the name of the student : Kapil Dev

Name is : Kapil Dev

Roll no is : 111

RESULT:

Thus the program is executed and its output is verified.

Exp.No .14

FILE

AIM

Write a program to illustrate the write() member function which are usually used for transfer of data blocks to the file

ALGORITHM

1. Start the process

2. Invoke the class

a. Create two inline member functions .ie, getdata() and dispdata()

i. getdata() for input

ii. dispdata() for display

3. Open the file in fstream mode

4. Write the data in to the file

5. Slose the file

6. Stop the process

PROGRAM

#include

#include

#include

class student

{

private:

int rno;

char name[10];

float fees;

public:

void getdata()

{

cout<<"roll number";

cin>>rno;

cout<

cout<<"enter name:";

cin>>name;

cout<<<"enter>

cin>>fees;

}

void dispdata()

{

cout<<"Roll number"<<

cout<<"Name"<<

cout<<"Fees"<

}

};

void main()

{

student s1;

clrscr();

ofstream stdfile("c:\\std.txt");

//fstream stdfile;

//stdfile.open("c:\\std.txt",ios::out|ios::in); //open file for output

char wish;

//writing to the file

do

{

s1.getdata();

stdfile.write((char*)&s1,sizeof(student));

cout<<"continue ? y/n";

cin>>wish;

}

while(wish=='y'||wish=='Y');

stdfile.close(); //close the file

getch();

}

OUTPUT

Roll number 121

Enter name Jacob

Enter fees 10000

RESULT:

Thus the program is executed and its output is verified.

Exp.No .15

COPYING ONE FILE TO ANOTHER FILE

AIM

A program to copy one file to another file and convert the lower case characters to upper case characters.

ALGORITHM

1) Start the process

2) Create the input file and out put file.

3) Get the input file name to fname1.

4) Get the output file name to fname2.

5) Open the infile(fanme1)

6) Check if infile.fail()

a) True:

i) Execute error conversion

ii) exit

7) open the outfile(fanme2)

8) check if outfile.fail()

a) repeat step(6:a)

9) check while infile.eof()

a) True:

i) Chß(char)infile.get()

10) Close both files

11) Stop the process.

PROGRAM :

#include

#include

#include

#include

#include

#include

void main( )

{

ofstream outfile;

ifstream infile;

char fname1[10],fname2[20];

char ch,uch;

clrscr( );

cout<<"Enter a file name to be copied ";

cin>> fname1;

cout<<"Enter new file name";

cin>>fname2;

infile.open(fname1);

if( infile.fail( ) )

{

cerr<< " No such a file Exit";

getch();

exit(1);

}

outfile.open( fname2);

if(outfile.fail( ))

{

cerr<<"Unable to create a file";

getch();

exit(1);

}

while( !infile.eof( ) )

{

ch = (char) infile.get( );

uch = toupper(ch);

outfile.put(uch);

}

infile.close( );

outfile.close( );

getch( );

}

OUTPUT:

Enter a file name to be copied.

C:\text1.txt

Enter new file name

D:\new.txt

Input file

Asbcdefghijklmnopqrstuvwxyz

Output file

ASBCDEFGHIJKLMNOPQRSTUVWXYZ

RESULT:

Thus the program is executed and its output is verified.