C++ FAQ

What are OOPS Concept.
http://www.exforsys.com/tutorials/c-plus-plus/basic-concepts-of-oops-and-structure-of-c-program.html


What is  virtual member function?
A virtual member function is a member function preceded by the keyword virtual or a member function
with the same signature  as a virtual function declared in the base class.

In this context, virtual means overridable  More specifically the keyword virtual means that the runtime
system automatically invoke the proper member function when it is overridden by a derived class.

A member function should be made virtual where there will be derived classes that will need to provide
their own implementation for member function.

How much does it cost to call virtual function compared to calling a normal function?
In theory, the overhead of dynamic binding is highly dependent on the compiler,operating
system and machine

A virtual function call typically cost 10 to 20 % more than a non virtual function call

How much c++ perform static typing while supporting dynamic binding?
static typing ensure that all declaration,definitions and uses of a virtual function are consistent
while dynamic binding provides the "plumbing" so that the right implementation is called at runtime.

Given a reference to an object, there are two distince types in question. the static type of the reference
and the dynamic type of the referent.

Compute the sum of all the values in the nodes of a single linked list

The only thing is needed to solve this problem is linked list traversal. So we can easily modify function getLenght into following solution:

Calculate length of the linked list

This problem can be easily solved by using simple recursion and again creates a basis for solving subset of related coding problems


What are the advantages and disadvantages of linked list structure vs. arrays?

Linked lists allow only sequential access to elements O(n) while arrays allow random access O(1). Linked lists requires an extra storage for references, which often makes them impractical for lists of small data items such as characters or Boolean values.


From the over side, size of array is restricted to declaration. Insertion/Deletion of values in arrays are very expensive comparing to linked list and requires memory reallocation. Elements can be inserted into linked lists indefinitely, while an array will eventually

Find point of intersection of two linked lists

Your are given two Nodes which correspond to the first elements of two linked lists which are merging at some point as show on the picture below.


Your are given two Nodes which correspond to the first elements of two linked lists which are merging at some point as show on the picture below.


1. Find lenghts (L1 and L2) of both list -- O(n) + O(n) = O(n)
2. Take the difference d of the lengths -- O(1)
3. Make d steps in longer list -- O(n)
4. Step in both lists in parallel until links to next node m
Can destructor be virtual?
Yes
 #include<iostream>  
 using namespace std;  
 class Base  
 {  
   public:  
     Base();  
     virtual ~Base()throw();  
 };  
 Base::Base()  
 {  
   cout<<" base constructor"<<endl;  
 }  
 Base::~Base()throw()  
 {  
   cout<<"base destrcutor"<<endl;  
 }  
 class derived : public Base  
 {  
   public:  
     derived();  
     ~derived()throw();  
 };  
 derived::derived()  
 {  
   cout<<"derived constrctor"<<endl;  
 }  
 derived::~derived()throw()  
 {  
   cout<<" derived destructor"<<endl;}  
 int main()  
 {  
    Base *p = new derived();  
    delete p;  
    return 0;  
 }  


Do we have virtual constructor?
NO

What is pure virtual member function?
a pure virtual member function is a member function that the base class
force derived class to provide.

Class shape
{
     public:
     virtual void draw()=0;
}

This pure virtual function make shape an asbtract class imagine that
the "=0" is like saying " the code for this function is at the null pointer"

Can a Pure virtual function be defined in the same class
Yes

Should a class with virtual function have at least one non inline virtual function
it is good idea
if the base class has a virtual destructor  the destrucotr in the derived class will also be virtual
unless specified and inline

like
class Base
{
       public:
       virtual ~Base() throw();
}
class derived : public Base
{

}

int main()
{

}

Even though no Base or derived objects are created the preceding example  will fall to link
on many system.The reason is that only virtual function in the derived class is inline
so the compiler put the static copy of  derived::~derived() into the current source file.

Since the static copy of the derived::~derived() invoke the Base::~Base(). the linker will need
a definition of the Base::~Base()


What is RTTI

RTTI stands for run time type identification. In the inheritance hierarchy using RTTI we can find exact type of object using a pointer or reference to the base class. The idea behind that virtual function is to upcast the derived class object Address into a pointer to a base class object and then the virtual function

Mechanism implement the correct behavior.

How to get information about the object at runtime
There are two ways to get information about the object at the runtime they are as follows.
Typeid() operator
Dynamic_cast operator

Class base {
Public:
Virtual Void fun()
{
Cout<<” base::fun”<<endl;
}
};
Class derived : public base
{
Public:
Void fun()
{
Cout<<”derived::fun”<<endl;
}
}
Int main()
{
Base *b,p,b1;
Derived d;
B=&d;
If(b1==dynamic_cast<derived *>(b))
Cout<<”base”
Else
Cout<<” derived class other”;
}

Can we get the typeid of void pointer
No

What is const_cast
The const_cast is used to convert const to a non const. This is shown in the following way.

#include<iostream>
Using namespace std;
Int main()
{
Const int a=2;
Int *p =const_cast<int*>(&a);
}

What is a reinterpret_cast
If for some reason we need to assign one kind of pointer type to another then weCan use reinterpret_cast.

What is static_cast
Castless conversion
Narrowing conversion
Conversion from the void*
Implicit type conversion

What is dynamic_casting

dynamic _casting can be used only with pointers and reference to objects. Its purpose is to ensure that the result of the type conversion is a valid complete object of the request class.
dynamic_cast is always successful when we cast a class to one of its base class.

Class cbase
{ }

Class cderived : public cbase { }
Int main()
{
Cbase base ,*ba;
Cderived d,*d1;
Ba=dynamic_cast<Cbase*>&d; //derived to base class
D1=dynamic_cast<cderived* >&base // base to derived class

It is an error.
The second conversion in the piece of the code would produce a compilation error since base to derived conversion are not allowed with dynamic_cast

Unless base class is polymorphic.
When a class is polymorphic dynamic_cast performs a special checking during
Runtime to ensure that the expression yields a valid object of the request class.

Dynamic_cast
#include<iostream>
#include<exception>
Using namespace std;

Class base
{
Public:
Virtual Void fun()
{
Cout<<”base::fun”<<endl;
}
}
Class derived : public base
{
Public:
Void fun()
{
Cout<<”derived::fun”<<endl;
}
}
Int main()
{
Try {
Base *b =new derived;
Base *b1 =new base;
Derived *d;
d=dynamic_cast<derived *>b;
if(d==0)
cout<<”Null pointer on first case”<<endl;
d=dynamic_cast<derived*>b1;
if(d==0)
cout<<”Null pointer on the second case”<<endl;
}
Catch(exception &e)
{
Cout<<e.exception<<endl;
}
}
For better understanding I wrote four case which will help to more analysis.
You can not assign base class object to derived class

Int main()
{
base *ba =new derived;
base *ba1 =new base;
derived *d;
base *ba2;

A)
d=dynamic_cast<derived*>(ba);
derived->derived (right->left)
if(d!=0)
cout<<" object assign"<<endl;
// ba2=dynamic_cast<base*>(ba);
Derived->base

B)
d=dynamic_cast<base*>(ba1);
wrong statement
base>derived (not possible)

c)
ba2=dynamic_cast<base*>(ba1);
base->base
if(ba2!=0)
cout<<"base clas object assign"<<endl;

base *bbb,bb1;
bbb=&bb1;
base *bb2;

D)
same sense above case just assign address
bb2=dynamic_cast<base*>(bbb);
if(bb2!=0)
cout<<" base class assign"<<endl;

E)
derived *ddd;
ddd=dynamic_cast<derived*>(bbb);
if(ddd==0)
cout<<" No object assign"<<endl;


F)
base *bb;
derived d1,*p;
bb=&d1;
p=dynamic_cast<derived*>(bb);
if(p!=0)
cout<<" derived"<<endl;


What is static type checking

Static type checking sometimes knows as static typing. Is when the compiler checks the type correctness of operation at compile time.

What is the basic problem with dynamic type checking
The basic problem with the dynamic type checking is that it uses code to find code creating extensibility problem later.
With dynamic type checking code has to be written to check the type of an object
To see if it support a particular set of member function.(this is the code that is doing the finding).

When user code uses code to find the sever code the user code is more complex
And fragile OO programming is supposed to encapsulate complexity and the

Improper use of dynamic type checking can undo this benefit.
Often dynamic type checking test require the user code to know the the server’s inheritance. In which case changing the server’s inheritance hierarchy break code. This is unlucky

How can dynamic type checking be avoided
Design Design and Design

Are there better alternatives to dynamic type checking
One alternative to dynamic type checking and down cast is dynamic binding

And virtual function
To use this alternative technique member function that shows up only in the
Derived class are generalized and moved up to the base class
Effectively this means that the class selection and down cast is performed automatically and safely C++.

The following example is a rework of the code. The old hierarchy, the italicsXXX() member function from the derived class are generalized and moved into the base class as virtual member function italics(). This result in a substantial simplification

Of the user code printUsingItalics().
Instead of selecting the printer type based on a type() member function and using
Control flow logic to figure out what to do the user code simply invoke the new
Italics() member function.

Class Printer
{
Public:
Virtual ~Printer throw();
Virtual void italics( const char *s) throw () =0;
}

Printer::~Printer() throw ()
{
}
Class EpsonPrinter :public Printer {
Public:
Virtual void italics(const char* s) throw();
};

Class EpsonPrinter ::italics(const char* s) throw ()
{
Cout<<esc<<”i+ “<<s<<esc<<”i-“;
}

This way it will continue ………….:

What is downcast
A downcast is the conversion of a Base* to a derived* where class Derived is
Publicly derived from class Base . A downcast is used when the client code thinks that Base* points to an object of class Derived or a class derived from the Derived and it needs to access a member function that is provided by Derived but not by base

What is an alternative to using downcast
Move the user code into the object in the form of the virtual function

Why are downcast dangerous
Downcast override the help a compiler can give and rely solely on the knowledge
Of the programmer
A downcast from the base class pointer to derived class pointer instructs the compiler to blindly reinterpret the bits of the pointer

Should the inheritance graph of c++ hierarchies be tall or short
The inheritance graph should be a forest of short tress

When the inheritance graph is too tall, downcast are common. This is because the type of the pointer is often different from the type of the object that the desired member function is available only by the downcasting the pointer.

downcasting & upcasting in Class Hierarchy
Is code reuse the main purpose of inheritance

The main purpose of inheritance is to express an externally meaningful relationship that describes the behavior of two entities within the problem domain. This relationship is called the is substitutable for relationship although

Sometimes the less accurate terms is-a or kind of are used instead.
The critical insight here is that inheritance springs out of the reality of the problem
Domain ,not out of a technical goal within the solution domain.

The most important code reuse that comes from the proper inheritance is the reuse in the large system of existing code that trusts that new derived class to

Be substitutable for the base class.
Inheritance can result in low level code reuse as a side effect but low level code
Reuse can also be gained from the composition, sometimes more appropriately than through inheritance

Template:
Function template definition
Sample<T> sample<T>::fun(sample s)
{
//code
}

Template class
Template <class T>
Class sample
{
T a;
T b;
Public:
T add ( T a,T b)
{
Return( a+b);
}

}

Int main()
{
Sample<int> a;
a.add(3,4);
return 0;
}


Bubble Sort

 void bubblesort (int a[] ,int n)  
 {  
 Int I,j,temp;  
 for(int I =0;i<n-1;i++)  
 {  
  for(int j=0;j<n-1-I; j++)  
  {  
   If(a[j] > a[j+1])  
   {  
    temp=a[j];  
    a[j]=a[j+1];  
    a[j+1]=a[j];  
   }  
  }  
 }  
 }   

Complexity =O(N^2);

Selection Sort


 Void selectionsort(int a[].int i)  
 {  
  int small,temp,selection;  
  for(int i=0; i<n ;i++)  
  {  
   small =a[i];  
   selection =i;  
   for( int j=i+1 ;j<=n ; j++)  
   {  
    If(small > a[j])  
    {  
     small =a[j];  
     Selection =j;  
    }  
   }  
   temp=a[i];  
   a[i]=small;  
   a[selection]=temp;  
  }  
 }  


Quick sort
 Void quicksort(int a[],int first,int last)  
 {  
  int temp;  
  int low =first;  
  int high =last;  
  int pivot =a[(first +last)/2];  
  do  
  {  
   While ( a[low]<pivot)  
   low++;  
   while(a[high]>pivot)  
   high++;  
   if(low<high)  
   {  
    temp =a[low];  
    low++;  
    a[high]=temp;  
    high++;  
   }  
  }while(low<=high) ;  
 If(low<last)  
 Quicksort(a[],low,last)  
 If(high<first)  
 Quicksort(a[],high,first)  
 }  

 We have noticed that it is much easier to sort short list than long ones.

If we can find a way to divide the list into two roughly same sized lists and short them separately we will save work. This way we can divide a problem into smaller but similar sub problem. We keep on dividing the list till there is only

One entry left.

Merger Sort

 Void merge sort(int a[],int n)  
 {  
  Int l1,l2,u1,u2;  
  Int k;  
  Int temp[4];  
  Int size =1;  
  Int I,j;  
  While(l1+size <n)  
  {  
   L2=l1+size;  
   U1=l2-1;  
   U2=l2+size-1;  
   If(u2>=n)  
     U2=n-1;  
   I=l1;  
   J=l2;  
   While(i<=u1 && j<=u2)  
   {  
    If(a[i]<=a[j])  
    temp[k++] =a[i++];  
    else  
    temp[k++] =a[j++];  
   }  
   While(i<=u1)  
    temp[k++] =a[i++];  
   While(j<=u2)  
    temp[k++]=a[j++];  
   L1=u2+1;  
  }  
  For(i=l1;k<=n;i++)  
  {  
  temp[k++]=a[i];  
  For(i=0;i<=n;i++)  
   a[i]=temp[i];  
  }  
 Size =size*2;  
 }  


To create Node in the list (simple link list)

 typedef struct node  
 {  
  int no;  
  struct node *next;  
 }node;  
 node *first =NULL;  
 Void addnode (int no)  
 {  
  node *p,*last;  
  P=(node*)malloc(sizeof(node));  
  p->no=no;  
  p->next=NULL;  
  if(first==NULL)  
    first=p;  
  else  
  {  
   last=first;  
   While(last!=NULL)  
    last=last->next;  
   last->next =p;  
  }  
 }  


The Program for the swap node
 Void swapnode()  
 {  
  node *last = first;  
  node *p,*q,*n;  
  while(last!=NULL && last->nex!=NULL)  
  {  
   p=last->next;  
   q=p->next;  
   last->next=p->next;  
   p->next=last;  
   if(last==first)  
    first=p;  
   else  
   n->next=p;  
   n=last;  
   last =q;  
  }
 }  

The Program for the reverse the link list

 Void reverse()  
 {  
  node *last,*p;  
  If(first->next==NULL)  
  {  
    cout<<” only one node”<<endl;  
  }  
  else  
  {  
   last=first->next;  
   first->next=NULL;  
   while(last!=null)   
   {  
    p=first;  
    first=last;  
    last=last->next;  
    first->next=p;  
   }  
  }  
 }  


Determining the Size of a Class Object

Dynamic_Cast


Dynamic_cast by reference

Handle Exception into constructor

Can we handle error handling in C leanguage
  • Yes with following way..

Some interesting question which we should know

Private Inheritance

Inheritance versus composition: Which one should you choose?
c++  Beginner Tutorial

No comments:

Post a Comment