Friday, September 24, 2010

C++ Professional Schdule

I am creating schedule for c++ professional which is mainly applicable to me :) but can be helpful for others. As a C++/Python Programmer, we should have good knowledge  in below topic.


C++                        http://cppcoffe.blogspot.in/2012/07/blog-post.html


Data Base              http://cppcoffe.blogspot.in/p/data-base.html
        
Python                   http://cppcoffe.blogspot.in/p/python-skill-and-interview.html



 STL              http://cppcoffe.blogspot.in/p/stl-url.html 

Coding website                              

Friday, August 20, 2010

c++ notes 2

Protected member function can not access into main function but it can be access into the derived class.


What is virtual base class.

When we write two derived class derive from the base class than we write new derive class which also derive two above class. It is called the virtual base class.

Code:
Class Base
{
Public:
Int data;
Base()
{
Data =0;
}
};

Class derived : virtual public Base
{
};
Class derived1 : virtual public Base
{
};

Class derived3 : public derived , public derived
{
Public:
Int getdata()
{
Return data;
}
};
Int main()
{
Derived d3;
Int a =d3.getdata();
}

a)Some changes if we remove virtual keyword from the derived class.
Than it will be compiler error.

base.cpp: In method `int derived3::getdata()':
base.cpp:37: request for member `data' is ambiguous in multiple inheritance lattice
base.cpp:8: candidates are: int base::data
base.cpp:8: int base::data

http://stackoverflow.com/questions/1321062/object-layout-in-case-of-virtual-functions-and-multiple-inheritance

http://www.phpcompiler.org/articles/virtualinheritance.html

http://www.ziddu.com/download/16618915/jangrayhood.pdf.html


b) if we write public virtual Base rather than virtual public Base than it does not impact anything Program run successfully.

Virtual  keyword 


Class base
{
Public:
void fun()
{
Cout<<” base::fun()”<<endl;
}
};

Class derived : public Base
{
Fun()
{
Cout<<” derived ::fun()”<<endl;
}
}

Int main()
{
Base *p,base;
Derived d;
P=&base;
p->fun();
p=&d;
p->fun();
}


Output :

Base ::fun()
Base ::fun()

if virtual keyword than
 
Output:

Base ::fun()
Derived ::fun()

Third Case

Class Base
{
Public:
Void virtual fun() - There is no error if u write virtual void or void virtual
{
Cout<<” base :: fun”<<endl;
}

};
Class derived :public base
{
Public :
Void fun()
{
Cout<<” derived::fun”<<endl;
}
};
Int main()
{
Base *p,base;
Derived d;
P=&base;
p->fun();
p=&d;
p->fun();
return 0;
}


Output
Base ::fun()
Derived ::fun()


Fourth Case


Class Base
{
Public:
Virtual void fun()
{
Cout<<” Base:: fun()”<<endl;
}
};
Class derived : public base
{
Public:
fun()  Change the signature from the base class
{
Cout<<” Derived :: fun()”<<endl;
}

Int main()
{

Base *b,base;
Derived d;
b=&base;
b->fun();
b=&d;
b->fun();
}


Output:

virtual.cpp:22: ANSI C++ forbids declaration `fun' with no type
virtual.cpp:22: conflicting return type specified for virtual function `int derived::fun()'
virtual.cpp:8: overriding definition as `void base::fun()'

Fifth Case:

Class Base

{
Public :
Virtual void fun()
{
Cout<<”Base::fun()”<<endl;
}
};
Class derived : public Base
{
Public :
I have removed fun function from the derived class
}
Int main
{
Base *p,base;
Derived d;
p=&base;
p->fun();
p=&d;
p->fun();
}

Output

Base ::fun()
Base ::fun()

Case Sixth

Class Base
{
Public:
Void fun()
{
Cout<<” Base::fun()”<<endl;
}
};
Class derived : public Base
{
Public:
Virtual void fun()  Adding virtual keyword in the derived class
{
Cout<<” Derived::fun()”<<endl;
}
};
Int main()
{
Base *p,base;
Derived d;
P=&base;
p->fun();
p=&base;
p->fun();
}

output
Base ::fun()
Base ::fun()

Case Seven

class base{
public :
virtual void fun()
{
   cout<<" Base ::fun()"<<endl;

}
};


class derived : public base
{
   public:
   void fun()
   {
           cout<<" derived::fun()"<<endl;
    }


   void method()
   {
           cout<<" base::method::fun()"<<endl;
    }


}


int main()
{
    base *p;
    derived d;
    p=&d;
    p->method();
 }

Output: 


virtual.cpp: In function 'int main()':
virtual.cpp: error: 'class base' has no member named 'method'


Case Eight C) wrong syntax




We can write base class in following way
a) Correct Syntax

Int main()
{
Base *p,base;
Derived d;
P=&base

p->fun();
p=&d;
p->fun();
}


b) Correct Syntax
int main()
{
Base *p,base;
Derived d;
p=new derived;
p->fun()
}



Int main()
{
Derived *d,d1;
Base base;
d =new base
d->fun();
d=&d1;
d->fun();
}

Error: type `derived' is not a base type for type `base'

d) wrong syntax
int main()
{
Derived *d,d1;
Base base;
D=&base;
d->fun();
d=&d1;
d->fun();
}
Error : type `derived' is not a base type for type `base'

What is virtual function

A virtual function or virtual method is a function or method whose behavior
Can be overridden within an inheriting class by a function with the same signature

What is kind of and has a relationship
What is iterator and iteration

Iterator is an object which moves in the container from the one element to another element and access the variable. The process of moving one element

From another element called iteration
When should the explicit keyword be used in the constructor ?

When we want that constructor should create object but it should not perform any
Implicit conversion than we should use the explicit keyword.


#include<iostream>
Class sample
{
Int I;
Explicit Sample(int ii =0)
{
I=ii;
}

Sample operator+(sample s)
{
Sample temp;
temp.i =i+s.i;
return temp;
}
Void display()
{
Cout<<I;
}
}
Int main()
{
Sample s1(15),s2;
S2=s1+15; //compilation error
S2.display();
}

How will you change the data member of the const object.

To change the date member of the const object the data members are declared
As mutable in the class.

#include<iostream>
Class sample
{
Private:
Mutable int I; - Mutable keyword
Public:
Sample(int ii=0)
{
I=ii;
}
Void fun() const  const object can access const function
{
I++;
}
};
Int main()
{
Const sample s(15);  const object.
s.fun();
}

More info about Const Variable.
http://www.cprogramming.com/tutorial/const_correctness.html

http://www.parashift.com/c++-faq-lite/const-correctness.html 

http://duramecho.com/ComputerInformation/WhyHowCppConst.html

What is friend function and when should be a function be made friend

A global function that can access that all data member of a class is called a friend function of that class. To make any function a friend of class it must be declared with the keyword friend function.

A function is made friend in the following two cases.
To access private data of a class from a non member function

To increase the versatility of overloaded operator
How does a friend function help in increasing the versatility of the overloaded operators

S2=s1*2
Where s1 and s2 are objects of the sample class. The statement works if the overloaded operator * (sample s) or conversion function is provided in the class.

Internally this statement occurs
S2=s1.operator*(2);

The function materializes because it is called with an object S1 the this pointer
Of s1 implicitly get passed.

But if we want to write the above statement as
S2=2*s1;

#include<iostream>
Class sample
{
Private
Int I;
Public:
Sample(int ii =0)
{
I =ii;
}
Void showdata()
{
Cout<<i<<endl;
}
Friend sample operator*(sample,sample);
};
Sample operator*(sample s1,sample s2)
{
Sample temp;
Temp.i=s1.i +s2.i;
Retrun temp;
}
Int main()
{
Sample s1(10),s2;
S2=s1*2;
S2.showdata();
S1=s2*2;
S1.showdata();
}

What is forward referencing and when should be used?

Class sample
{
Public:
Friend void fun(sample,test);
};
Class test
{
Public:
Friend void fun(sample,test);
}

Int main()
{
Sample s;
Test t; }

Write one case where friend function becomes necessary

When we want user user defined object should be print through cout than we overload operator <<.

Class sample
{
Char name[20];
Int age;
Float sal;

Public:
Friend ostream& operator<<(ostream &o, sample &a);
Friend istream& operator>>(istream &I,sample &a);
}
Ostream& operator<<(ostream &o, sample &a)
{
O<<a.name<<a.age<<a.sal;
Return o;
}
Istream& operator>>(istream &I, sample &a)
{
i>>a.name>>a.age>>a.sal;
return I;
}
Int main()
{
Sample s;
Cin>>s;
Cout<<s;
}

Is it necessary that while using pointer to member with data the data must be made public

Yes the private data member are never accessible outside the class

How would you define a point to data member of the type pointer to pointer

Class sample
{
Public:
Sample(int **pp)
{
p=pp;
}
Int **p;
}
Int **sample:: *ptr = &sample::p;
Int main()
{
Int i=9;
Int *s =&I;
Sample sa(&s);
Cout<<**(s.*ptr);
}

Can we create a pointer to member function
Class sample
{
Public:
Void fun()
{
Cout<<”func with the pointer”<<endl;
}
};
Void (sample:: *pfun()) =&sample::fun;
Int main()
{
Sample s;
(s.*pfub()) ();
}

Some more info
http://www.eskimo.com/~scs/cclass/int/sx10b.html

What is namespace

While developing a program different header file are included. It may happen that some header file contain same function or class name. Trying to access these function or classed may lead to be an ambiguity. Such ambiguity can be

Avoided using namespace.
How to refer to a name of class or function that is defined within a namespace

Namespace name1
{
Class sample1
{
//code
}
}
Namespace name2
{
Class sample2
{
//code
}
}
Using namespace sample2;
Int main()
{
Name1:: sample s1;
Sample2 s2;
}


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 objectAddress into a pointer to a base class object and then the virtual function

Mechanism implement the correct behavior.

Thursday, August 19, 2010

c++ Notes

Constructor:

Class X
{
int i;
public:
X();
}
void f() is
{
X a;
}
the same thing happen as if a were an int. Storage is allocated for object But when the program reaches the sequence point(point of execution) where a is defined, the constructor is called automatically. That is, the compiler quietly insert the
call to X::X() for the object a at point of definition. like any member function the first secret argument to the constructor is the this pointer the address of the object for which it is being called .in the case of constructor however this is pointing  to an unintialized block of memory and it is job of the constructor to intialize this memory properly.

If u have constructor with the argument than you can initialize object with argument. Tree a(2).

Constructor and destructor can not have return value.
In the Destructor never has any argument because destruction never need any option.
Class Y {
Public:
~Y();
};

Example of constructor and destructors
#include<iostream>
Using namespace std;

Class Tree
{
Int height;
Public :
Tree( initialHeight);
~Tree();
Void grow(int years);
Void printsize();
Void grow(int years);
Void printsize();
};
like any function, the constructor can have argument to allow you to specify how an object is created.
A default constructor is one that can be called with no argument.

Storage allocation:

A variable can now be defined at any point in a scope. So it might seem that the storage for the variable may not be defined until its point of definition.
The storage is allocated at the beginning begining of the block, the constructor
Call does not happen until the sequence point where the object is defined because the identifier is not available until then.


Aggregate initialization
 
An aggregate is just what it sounds like : a bunch of things clumped together.

This definition includes aggregates of mixed types like struct and classes. An array is an aggregate of a single type.
When you create an object that’s an aggregate all you must do is make assignment and the initialization will be taken care of by the compiler.
This assignment can be in several flavors For an array of built in type this is quite simple
Int a[5] ={1,2,3,4,5}
If u try to give more initializers than there are array element , the compiler gives an error message.
Int b[6] ={0}
A second shorthand for arrays is automatic counting in which you let the compiler
Determine the size of the array based on the number of initializers.
Int c[] ={ 1,2,3,4 }

Now if you decide to add another element to the array you simply add another initialize.

The size of array will be sizeof c /sizeof *c ( size of the entire array deivided by the size of the first element)

For(int I =0; i< sizeof c/ sizeof *c ;i++)
C[i]++;

Structure are also aggregates , they can be initialized in a similar fashion. Because a C style struct has all of its members.

Struct X
{
Int I;
Float f;
Char c;
};

X x1 ={1,2.2.’c’}
If you have an array of such object you can initialize them by using a nested set of curly braces for each object.
X x2[3] ={ {1,1.1,’a’} , {2,2.2.,’b’}}
Here the third object is initialized to zero.

If you have struct with all members public or a class with private data member all the initialization must go through the constructor even if you are using aggregat Initialization.

Second example showing multiple constructor argument.

#include<iostream>
Using namespace std;

Class z {
Int I,j;
Public:
Z(int ii ,int jj);
Void print ();
};
Z::Z(int ii , int jj)
{
I =ii;
J=jj;
}

Void Z::print() {
Cout<<” I =”<<I <<” j=”<<j<<endl;
}

Int main()
{
Z zz[] = { Z(1,2) ,Z(3,4) , Z(5,6) ,Z(7,8) };
For(int I =0 ; i< sizeof zz / sizeof *zz ; i++)
Zz[i].print();

Notice that it look like an explicit constructor is called for each object in the array.
}

Default constructor:
A default constructor is one that can be called with no argument. A default constructor is used to create a “vanilla object” but it is also important when the

Compiler is told to create an object but is not given details.
For Example if you take the struct Y defined previously and use it in a definition like this .
Y y2[2] ={ Y(1) };
The complier will complain that it can not find a default constructor.
The second object in the array wants to be created with no argument
And that’s where the compiler looks for a default constructor.
In fact if you simply define an array of objects
Y y3[7];
The complier will complain because it must have a default constructor to initialize every object in the array.
The default constructor is so important if and only if there are no constructor for a constructor

Function overloading and default argument
More name decoration

The concept of name decoration was introduced.
Void f()
Class X
{
Void f();
}
The function f() inside the scope of class X does not clash with the global version of f().
The compiler perform this scoping by the manufacturing different internal name for the global version of f()and X::f().

It was suggested that the name are simply the class name “decorated” together
Function name so the internal names the compiler uses might be _f and _X_f.
The compiler will give the name with the argument list with function name. it does not generate compiler name only with the function name.

Overloading does not depend on the return value

Type Safe linkage

There is an added benefit to all of this name decoration. A particularly sticky problem in c occurs when the client programmer misdeclares function or worse a function is called without declaring it first and the compiler infers the function declaration from the way it is called. Sometimes this function declaration is correct but when it is not it can be a difficult bug to find.

Because all functions must be declared before they used in c++ . the opportunity for this problem are very rarely.
The c++ compiler refuses to declare a function automatically for you . so it is likely that you will include the appropriate header file.
However if for some reason you still manage a misdeclare a function either by declaring by hand or including the wrong header file the name decoration provides a safety net that is often referred to as type safe linkage.
Consider the following scenario. In one file is the definition for the function.
Void f(int){}
In the second file the function is not declare properly then called.
Void f(char);

Int main() {

// f(1)
}

Even though you can see that the function is actually f(int) the compiler does not know because it was told – through the explicit declaration that the function is f(char). Thus the compilation is successful.

In c the linker would also be successful but not in c++ Because the complier decorates the names the definition becomes something like f_int whereas the use of the function is f_char.

When the linker tries to resolve the reference to f_char it can only find f_int and give you error message.

Overloading Example

We can now modify earlier example to use function overloading.

As stated before an immediately useful place for overloading is in constructor.

You can see this in the following version of the stash.

Class Stash
{
Int size;
Int quantity;
Int next;

Unsigned char* storage;
Void inflate(int increase);

Public:
Stash(int size);
Stash(int size , int initQuantity);

~Stash();
Int add(void *element);
Void *fetch(int index);
Int count();

};

The first stash() constructor is the same as before but the second one has a Quantity argument to indicate the initial number of the storage places to b Allocated.
In the definition, you can see that the internal value of quantity is set to zero.Along with the storage pointer.

Overloading does not depend on the return value.


Unions

As you have seen the only difference between struct and class in C++ is that Struct default to public and class default to private.

Union can also have a constructor, destructor ,member function and even access control.


#include<iostream>
Using namespace std;

Union U {

Private:
Int I;
Float f;

Public :
U(int a);
U(float b);

~U();
Int read_int();
Float read_float();
};

U::U(int a)
{
I=a;
}
U::U(float b) { f =b; }
U::~U()
{
Cout<<” U::~U()\n”; }

Int U:: read_int()
{ return I;
}

Float U :: read_float()
{
Return f;
}

Int main()
{
U X(12),Y(1.9F);
}

You might think from the code above that the only difference between a union and class is the way the data is stored. ( int and float are overlaid on the same piece of storage).

Union can not be used as a base class during inheritance.

Although the member functions civilize access to the union somewhat there is still no way to prevent the client programmer from the selecting the wrong element type once the union is initialized.


In the example above you could say X.read_float() even though it is inappropriate.( you are float function to integer object)

However a “safe” union can be encapsulated in a class.


#include<iostream>

Using namespace std;


Class SuperVar {
Enum {
Character,
Integer,
Floating_point
}varitype;


Enum has no typename ( it is untagged enumeration) .This is acceptable if you are going to immediately define instances of the enum


Union {
Char c;
Int I;
Float f;
};


The union has no type name and no variable name. This is called an anonymous union and create space for union but does not require accessing the union element with a variable name and dot operator.


Public:
SuperVar(char ch);
SuperVar(int ii);
SuperVar(float ff);
Void print();


};


SuperVar::SuperVar(char ch)
{
Vartype =character;
C=ch;
}


SuperVar::SuperVar(int ii)
{
Vartype =integer;
I=ii;
}


SuperVar::SuperVar(float ff)
{
Vartype =floating_point;
F= FF;
}
Void SuperVar::print() {
Switch(vartype) {
Case character :
Cout<<” character “<<c<<endl;
Break;
Case integer :
Cout<<”integer “<<i<<endl;
Break;
Case floating_point:
Cout<<”float”<<f<<endl;
Break;
}
}


Int main()
{
SuperVar A(‘c’), B(12),c(1.4F);
}


The first purpose of the union in the first place to save union.

Default argument:



C++ provides a remedy default argument. A default argument is a value given in the declaration that the compiler automatically inserts if you do not provide a value in the function call.
Stash(int size);


Stash(int size, int quantity =0);

Default arguments are a convenience as function overloading is a convenience.
Both feature allow you to use a single fuction name in different situation.


The difference is that with default arguments the complier is substituting argument when you do not want to put them in yourself.
If the function have very different behaviors it does not make sense to use default argument.


There are two rules you must be aware of when using default argument.
First only trailing argument may be defaulted .That ‘s you can not have
A default argument followed by the non default argument.


Once you start using default argument in a particular function call , the subsequent argument in that function’s argument list must be defaulted.


Function overloading simple facts

http://codepad.org/LfOfvwOj

http://codepad.org/2ETEJcEG#comment-Yk8miiVk

http://codepad.org/tWoRl7dN

http://msdn.microsoft.com/en-us/library/kbd4xa4d.aspx

 

Placeholder Argument

Argument in a function declaration can be declared without identifiers.Const in header file
A const in C++ defaults to internal linkage that is it is visible only within the file where it is defined and can not be seen at link time by other translation unit. You must always assign a value to const where it is defined and can not seen at the link by the other translation unit. You must always assign a value to a const when


You define it. Expect when you make an explicit declaration using extern.



  • Extern const int bufsize :Normally the C++ compiler avoid creating storage for a const but instead hold the  Definitions in its symbol table. When we extern keyword it forces us to allocate storage.
           Extern says “use external linkage”

Safety Consts
The use of const is not limited to replacing #define in constant expression. If you initialize a variable with a value that is produced at the runtime and you will not change for the lifetime of that variable.

#include<iostream>
Using namespace std;
Const int i=100;
Const int j= i+10;
Long address =(long)&j;
Char buf[j+10];


Int main()
{
Cout<<” type a character”<<endl;
Const char c= cin.get() //can not chage
Const char c2 =c+’a’;
Const<<c2;
}


Difference with C++
The meaning of const in C “an ordinary variable that can not be changed”
In C a const always occupies storage and its name is global. The C compiler can not treat const as compile time constant.

In C if you say
Const
int bufsize =100;
Char buf[bufsize];

You will get an error even though it seems like a rational things to do. Because bufsize occupies storage somewhere. The C compiler can not know the value at compile time. You can optionally say

Const int bufsize;
C defaults to external linkage for consts this make sense. C++ defaults to internal linkage for const . So if you want to accomplish the same things in c++

You must explicitly change the linkage to external using extern.
Extern const int bufsize;

This line also works in C.
In C++, a const does not necessarily create storage. In C a const always create

Storage.
In C++ a const that is outside all function has file scope (i.e. it is invisible outside
The file. That is, it is default to internal linkage.

This is very different from all other identifiers in c++ that default to external linkage. Thus if you declare a const of the same name in two different file

And you do not take the address or define that name as extern. The ideal c++
Compiler will not allocate storage for the const but simply fold it into the code.

PointerWhen using const with pointer you have two options
Const can be applied to what the pointer is pointing to.

Const can be applied to the address stored in the pointer itself.

Pointer to Const
So if you want to prevent any changes to the element you are pointing to you write a definition like this.

Const int *u;
U is a pointer which points to a const int

Int const *V
V is const pointer to an int

Both the effect are same.
Const pointer

Int d =1;
Int * const w= &d;

W is pointer which is const that point to int.
Assignment and type checking

C++ is very particular about type checking and this extends to pointer assignment. You can assign the address of a non const object to a const

Pointer because you are simply promising not to change something that is
Ok to change.
You can not assign the address of a const object to a non const pointer.

Character array literals
The place where strict constness is not enforced is with character array literals.
Char *cp =”howdy”

The compiler will accept it without complaint. This is technically an error because

Because a character array literal is created by the compiler as a constant character array and the result of the quoted character array is its starting address

In memory.
If you want to be able to modify the string put it in an array
Char cp[] =”howbdy”

Function arguments & return values
Passing by const value
You can specify that function arguments are const when passing them by value such as

Void f1(const int i) {
I++; compile time error
}
The const takes on meaning the argument can not be changed .so it is really tool
For the creator and not the caller.

Returning by the const value
A similar truth hold for the return value. If you say that function’s return value is const.
Const int g().

You are promising that original variable will not be modified inside the function.
Int f3() { return 1;}

Const int f4() { return 1; }
Int main()
{
Const int j =f3(); //works fine
Int k =f4(); // But this works fine too
}
For built in types it does not matter whether you return by value as const so you avoid confusing the client programmer and leave off the const when returning a built in type by value.

Returning by value as a const becomes important when you are dealing with user defined types.
Class X {
Int I;
Public:
X(int ii =0);
Void modify();
};

X::X(int ii)
{
I =ii;
}

Void X::modify()
{
I++;
}

X f5() - No constant
{
Return X();
}

Const X f6() { - Return Constant
Return X();
}

Void f7(X& x)  Pass by Const
{
x.modify();
}
}

Int main()
{
F5() = X(1); //ok non const return value
F5() return a non const X object while f6() return a const X object. Only the non const return value can be used as an lvalue.

Passing and returning addresses
Page No 349 (Thinking in c++)

If you pass or return an address( either a pointer or reference) it’s possible for the client programmer to take it and modify the original value.
If you make the pointer or reference a const you prevent this from happening.
In fact when you are passing an address into a function, you should make it a const if at all possible.

The choice of whether to return a pointer or reference to a const depends on what you want to allow your client programmer to do with it.

Void t(int *) { } - ordinary pointer
Void u(const int* cip)
{
*cip =2 // illegal Modifing value.
Int I = *cip // ok copies value
Int *p2 =cip // illegal non const value
}


Const char *v() {
// Return address of static character array
Return “result of function v()”
}

Const int * const w () {
Static int I;
Return &I;
}

Int main()
{
Int x =0;
Int *ip =&x;
Const int *cip =&x;
T(ip); //ok
// t(cip) //Not ok you can not assign const pointer to non const pointer
U(ip) //ok

U(cip) // ok
Char *cp =v() // not ok
Const char *ccp =v(); //ok
Int *ip2 =w(); //Not ok

Const int* const ccip =w(); //ok
Const int* cip2 =w() //ok
*w() =1 // Not ok

}

Standard argument Passing
In C it is very common to pass by value and when you want to pass an address your only choice is to use pointer.
In C++ your first choice pass by reference and by const reference at that.
Because of the syntax reference, it is possible to pass a temporary object to a function that takes a const reference. In the other case you can never pass a temporary object to function that takes a pointer.

With a pointer, the address must be explicitly taken.
The example will better explain.

ConstTemporary.cpp
Class X {};
X f() { return X(); }
Void g1(X&) {} // Pass by the non const reference.


Void g2(const X&) { }
Int main()
{
// g1(f())
// Error: const temporary created by the ()
// g2(f())
}

F() returns an objects of class X by value. That means when you immediately take the return value of f() and pass it to another function as in the calls to g1() and g2(), a temporary is created and that temporary is const.

The call in g1() is an error because g1() does not take a const reference but the call to g2() is ok

Classes
This section shows the way you can use const with classes. You may want to create a local const in a class to use inside constant expression that will be

Evaluated at the compile time.
Const in classes
One of the places you did like to use a const for constant expression is inside classes. The typical example is when you are creating an array inside a class

And you want to use a const instead of a #define to establish the array size
And to use in calculation involving the array. The array size is something you did like to keep hidden inside the class. So if you used a name like size for example

You could use that name in another class without a clash.
The preprocessor treats all #define as global from the point they are defined, so

This will not achieve the desire effect.

The constructor initialize list
The special initialization point is called the constructor initialize list and it was originally developed for use in inheritance.

The constructor initializer list – which as the name implies, occur only in the definition of the constructor.
The proper form for const inside a class is shown here.

#include<iostream>
Using namespace std;
Class Fred
{
Const int size;
Public:
Fred(int sz);
Void print()
};

Fred :: Fred(int sz) : size(sz) {}
Void Fred :: print() { cout <<”size “<<endl}

Int main()
{
Fred a(1),b(2),c(3);
a.print(),b.print(),c.print();
}

“Constructor” for built in type
You can treat a built in type as if it has a constructor like this.


#include<iostream>
Using namespace std;

Class B
{
Int I;
Public:
B(int ii);
Void print()
};

B::B(int ii) : i(ii) { }
Void B::print() {
Cout<<I <<endl;
}

Int main()
{
B a(1),b(2);
}

Compile time constants in classes
The above use of const is interesting and probably useful in cases but it does not solve the original problem.

The static keyword in this situation means “there is only one instances regardless of how many objects of the classes are created”
There is one feature of static const when used inside the classes which is bit unusal, you must provide the initialize at the point of definition of the static const

#include<string>
#include<iostream>

Using namespace std;
Class StringStack
{
Static const int size =100;
Const string* stack[size];

int index;
}
The “enum hack” in old code
In older version of c++, static const was not supported inside classes. This meant

The const was useless for constant expression inside the classes.
#include<iostream>
Using namespace std;

Class Bunch {
Enum { size =100};
Int i[size];
};

Int main()
{
Cout<<” sizeof (bunch) “<<sizeof(bunch)<<endl;
}
The use of enum here is guaranteed to occupy no storage in the object.
Enum { one =1, two =2, three };
The compiler will continue counting from the last value so the enumerator three will get the value 3


http://codepad.org/FFQR9O5A


Cosnt objects & member funciton
Class member function can be made const.

A const object is defined the same for a user defined type as a built in type.
Const int I =1;
Page no 359

Static variable inside the function
The storage for this object is not on the stack but instead in the program’s static
data area. This object is initialized only once the first time the function is called
and retain its value between function invocation

if you do not provide an initialize for a static variable of a built in type, the compiler guarantees that variable will be initialized to zero.
Static class objects inside function.The rules are the same for static objects of user-defined types, including the fact that some initialization is required for the object.

User defined types must be initialized with the constructor calls.
Using namespace std;

Class X {
Int I;
Public:
X(int ii =0) :i(ii) {} //default
~X() { cout<<” X:: ~X()”<<endl; }
};

Void f() {
Static X x1(47);

Static X x2; // default constructor required
}

Int main() {
F()
}

Deep copy Program
http://codepad.org/IFjgA6fd

Static object destructors
Destructor for static objects are called when main() exits or when the standard C library function exit() is explicitly called.

Controlling linkage
Any name at file scope is visible throughout all translation unit in a program This is often called external linkage Static is local to its translation unit. That names has internal linkage .This means
That you can use the same name in other translation unit without a name clash

One advantage to internal linkage is that the name can be placed in a header file
Without worrying that there will be clash at link time

Static VS global
If I declare in the file following function. It will represent two things

Int a=0;
The storage for a will be in the program’s static data area and the initialization
For a will occur once before main() entered. In the addition the visibility of a is global across all translation unit.

If it is
Static int a =0;
The variable a has internal linkage the storage class unchanged but scope is limited to file lavel

If it is
Using namespace std;
Int main()
{
Extern int I;
Std::cout << I;
}

In another file
Int I =5;

It is same like global function


Others storage class specifiers
Because C++ does not know much about your class, the default copy constructor and default assignment operators it provides use a copying method known as a shallow copy (also known as a memberwise copy).

A shallow copy means that C++ copies each member of the class individually using the assignment operator. When classes are simple (eg. do not contain any dynamically allocated memory), this works very well.

For example, let’s take a look at our Cents class

class Cents
{
private:
int m_nCents;

public:
Cents(int nCents=0)
{
m_nCents = nCents;
}
};

When C++ does a shallow copy of this class, it will copy m_nCents using the standard integer assignment operator. Since this is exactly what we’d be doing anyway if we wrote our own copy constructor or overloaded assignment operator, there’s really no reason to write our own version of these functions!


However, when designing classes that handle dynamically allocated memory, memberwise (shallow) copying can get us in a lot of trouble! This is because the standard pointer assignment operator just copies the address of the pointer — it does not allocate any memory or copy the contents being pointed to!

Let’s take a look at an example of this:

class MyString
{
private:
char *m_pchString;
int m_nLength;

public:
MyString(char *pchString="")
{
// Find the length of the string
// Plus one character for a terminator

m_nLength = strlen(pchString) + 1;
// Allocate a buffer equal to this length

m_pchString= new char[m_nLength];
// Copy the parameter into our internal buffer

strncpy(m_pchString, pchString, m_nLength);
// Make sure the string is terminated

m_pchString[m_nLength-1] = '\\0';
}


~MyString() // destructor
{
// We need to deallocate our buffer
delete[] m_pchString;
// Set m_pchString to null just in case
m_pchString = 0;
}

char* GetString() { return m_pchString; }

int GetLength() { return m_nLength; }

};


The above is a simple string class that allocates memory to hold a string that we pass in. Note that we have not defined a copy constructor or overloaded assignment operator. Consequently, C++ will provide a default copy constructor and default assignment operator that do a shallow copy.

Now, consider the following snippet of code:

MyString cHello("Hello, world!");
{
MyString cCopy = cHello; // use default copy constructor
} // cCopy goes out of scope here

std::cout << cHello.GetString() << std::endl; // this will crash

While this code looks harmless enough, it contains an insidious problem that will cause the program to crash! Can you spot it? Don’t worry if you can’t, it’s rather subtle.

Let’s break down this example line by line:

MyString cHello("Hello, world!");

This line is harmless enough. This calls the MyString constructor, which allocates some memory, sets cHello.m_pchString to point to it, and then copies the string “Hello, world!” into it

MyString cCopy = cHello; // use default copy constructor

This line seems harmless enough as well, but it’s actually the source of our problem! When this line is evaluated, C++ will use the default copy constructor (because we haven’t provided our own), which does a shallow pointer copy on cHello.m_pchString. Because a shallow pointer copy just copies the address of the pointer, the address of cHello.m_pchString is copied into cCopy.m_pchString. As a result, cCopy.m_pchString and cHello.m_pchString are now both pointing to the same piece of memory!

} // cCopy goes out of scope here

When cCopy goes out of scope, the MyString destructor is called on cCopy. The destructor deletes the dynamically allocated memory that both cCopy.m_pchString and cHello.m_pchString are pointing to! Consequently, by deleting cCopy, we’ve also (inadvertently) affected cHello. Note that the destructor will set cCopy.m_pchString to 0, but cHello.m_pchString will be left pointing to the deleted (invalid) memory!

std::cout << cHello.GetString() << std::endl;

Now you can see why this crashes. We deleted the string that cHello was pointing to, and now we are trying to print the value of memory that is no longer allocated.

The root of this problem is the shallow copy done by the copy constructor — doing a shallow copy on pointer values in a copy constructor or overloaded assignment operator is almost always asking for trouble.

Deep copying

The answer to this problem is to do a deep copy on any non-null pointers being copied. A deep copy duplicates the object or variable being pointed to so that the destination (the object being assigned to) receives it’s own local copy. This way, the destination can do whatever it wants to it’s local copy and the object that was copied from will not be affected. Doing deep copies requires that we write our own copy constructors and overloaded assignment operators.

Let’s go ahead and show how this is done for our MyString class:

// Copy constructor

MyString::MyString(const MyString& cSource)

{

// because m_nLength is not a pointer, we can shallow copy it
m_nLength = cSource.m_nLength;

// m_pchString is a pointer, so we need to deep copy it if it is non-null
if (cSource.m_pchString)
{
// allocate memory for our copy
m_pchString = new char[m_nLength];

// Copy the string into our newly allocated memory
strncpy(m_pchString, cSource.m_pchString, m_nLength);
}
else
m_pchString = 0;
}

As you can see, this is quite a bit more involved than a simple shallow copy! First, we have to check to make sure cSource even has a string (line 8). If it does, then we allocate enough memory to hold a copy of that string (line 11). Finally, we have to manually copy the string using strncpy() (line 14).

Now let’s do the overloaded assignment operator. The overloaded assignment operator is a tad bit trickier:


// Assignment operator

MyString& MyString::operator=(const MyString& cSource)
{
// check for self-assignment
if (this == &cSource)
return *this;

// first we need to deallocate any value that this string is holding!
delete[] m_pchString;
// because m_nLength is not a pointer, we can shallow copy it

m_nLength = cSource.m_nLength;
// now we need to deep copy m_pchString

if (cSource.m_pchString)
{
// allocate memory for our copy
m_pchString = new char[m_nLength];

// Copy the parameter the newly allocated memory
strncpy(m_pchString, cSource.m_pchString, m_nLength);
}
else
m_pchString = 0;

return *this;
}

Note that our assignment operator is very similar to our copy constructor, but there are three major differences:

We added a self-assignment check (line 5).
We return *this so we can chain the assignment operator (line 26).

We need to explicitly deallocate any value that the string is already holding (line 9).
When the overloaded assignment operator is called, the item being assigned to may already contain a previous value, which we need to make sure we clean up before we assign memory for new values. For non-dynamically allocated variables (which are a fixed size), we don’t have to bother because the new value just overwrite the old one. However, for dynamically allocated variables, we need to explicitly deallocate any old memory before we allocate any new memory. If we don’t, the code will not crash, but we will have a memory leak that will eat away our free memory every time we do an assignment!


Deep copy in my words
I wrote simple and get crash and did little bit analysis on this issue.


#include<iostream>
using namespace std;

class sample
{
  char *c_string;
  public:
  sample()
  {
        cout<<" the default constructor is "<<endl;
  }
  sample(char *p)
  {
      int i=0;
      while(p[i]!='\0')
             i++;

      c_string =new char[i+1];

      i=0;
      while(p[i]!='\0')
      {
             c_string[i]=p[i];
             i++;
      }

    char* getstring()
 {
     return c_string;
 }

 ~sample()
 {

    delete[] c_string;
  }
};

int main()
{
   sample c("hello");
   {
    sample copy =c; // want to write this line so i have put fix and find the program below
   }
   cout<<"The value of c"<<c.getstring()<<endl<<endl;
   return 0;
}


So I saw program crash i hope you have got understanding from the above article.

The value of c

*** glibc detected *** ./sh: double free or corruption (fasttop): 0x00000000154f1010 ***
======= Backtrace: =========
/lib64/libc.so.6[0x2add27eb82ef]
/lib64/libc.so.6(cfree+0x4b)[0x2add27eb873b]
./sh(__gxx_personality_v0+0x2dc)[0x400ac4]
./sh(__gxx_personality_v0+0x1e4)[0x4009cc]
/lib64/libc.so.6(__libc_start_main+0xf4)[0x2add27e63994]
./sh(__gxx_personality_v0+0x51)[0x400839]
======= Memory map: ========
00400000-00401000 r-xp 00000000 00:1a 1365237173                         /x/home-new/agoswami/my_work/sh
00601000-00602000 rw-p 00001000 00:1a 1365237173                         /x/home-new/agoswami/my_work/sh
154f1000-15512000 rw-p 154f1000 00:00 0                                  [heap]
2add27497000-2add274b3000 r-xp 00000000 fd:00 786434                     /lib64/ld-2.5.so
2add274b3000-2add274b5000 rw-p 2add274b3000 00:00 0
2add274c8000-2add274c9000 rw-p 2add274c8000 00:00 0
2add276b2000-2add276b3000 r--p 0001b000 fd:00 786434                     /lib64/ld-2.5.so
2add276b3000-2add276b4000 rw-p 0001c000 fd:00 786434                     /lib64/ld-2.5.so
2add276b4000-2add2779a000 r-xp 00000000 fd:00 1153587                    /usr/lib64/libstdc++.so.6.0.8
2add2779a000-2add27999000 ---p 000e6000 fd:00 1153587                    /usr/lib64/libstdc++.so.6.0.8
2add27999000-2add2799f000 r--p 000e5000 fd:00 1153587                    /usr/lib64/libstdc++.so.6.0.8
2add2799f000-2add279a2000 rw-p 000eb000 fd:00 1153587                    /usr/lib64/libstdc++.so.6.0.8
2add279a2000-2add279b4000 rw-p 2add279a2000 00:00 0
2add279b4000-2add27a36000 r-xp 00000000 fd:00 786449                     /lib64/libm-2.5.so
2add27a36000-2add27c35000 ---p 00082000 fd:00 786449                     /lib64/libm-2.5.so
2add27c35000-2add27c36000 r--p 00081000 fd:00 786449                     /lib64/libm-2.5.so
2add27c36000-2add27c37000 rw-p 00082000 fd:00 786449                     /lib64/libm-2.5.so
2add27c37000-2add27c44000 r-xp 00000000 fd:00 786486                     /lib64/libgcc_s-4.1.2-20080825.so.1
2add27c44000-2add27e44000 ---p 0000d000 fd:00 786486                     /lib64/libgcc_s-4.1.2-20080825.so.1
2add27e44000-2add27e45000 rw-p 0000d000 fd:00 786486                     /lib64/libgcc_s-4.1.2-20080825.so.1
2add27e45000-2add27e46000 rw-p 2add27e45000 00:00 0
2add27e46000-2add27f93000 r-xp 00000000 fd:00 786441                     /lib64/libc-2.5.so
2add27f93000-2add28193000 ---p 0014d000 fd:00 786441                     /lib64/libc-2.5.so
2add28193000-2add28197000 r--p 0014d000 fd:00 786441                     /lib64/libc-2.5.so
2add28197000-2add28198000 rw-p 00151000 fd:00 786441                     /lib64/libc-2.5.so
2add28198000-2add2819e000 rw-p 2add28198000 00:00 0
7fffac843000-7fffac858000 rw-p 7ffffffea000 00:00 0                      [stack]
ffffffffff600000-ffffffffffe00000 ---p 00000000 00:00 0                  [vdso]
Aborted

sample(const sample& s)
  {

          int i=0;
          while(s.c_string[i]='\0')
                i++;

          c_string=new char[i+1];

          i=0;
          while(s.c_string[i]!='\0')
          {
                  c_string[i]=s.c_string[i];
                  i++;
          }
          c_string[i]='\0';
   }



so i  addes this function and able to write this line


but In main I want to write the below line.

sample d;
d=c;


than i have to write the following function.

char* operator=(const sample &s)
  {
          int  i=0;
          while(s.c_string[i]!='\0')
                   i++;

          c_string =new char[i+1];

          i=0;
          while(s.c_string[i]!='\0')
          {
                c_string[i] =s.c_string[i];
                i++;
           }
           c_string[i]='\0';
           return c_string;

   }

Sunday, August 15, 2010

C++ Program list6

The Program list
1. The Program for the doubly circular
2. The Program for hcf & lcm
3. Program for quick sort 
4. Stack Operation


/*

* The Program for the doubly circular
* */
#include<iostream>


using namespace std;
template<class T>
class node
{
public:
T data;
node<T> *next;
node<T> *pre;
};
template<class T>
class link_1
{
public:
link_1();
void create_link_1_list(T data);
void add_after(T data);
void add_before(T data);
void delete_after(T data);
void delete_before(T data);
node<T> *first;
template<typename T2>
friend ostream& operator<< (ostream &o,link_1<T2> li);
};

template<class T>
link_1<T>::link_1()
{
first=NULL;
}

template<class T>
void link_1<T>::create_link_1_list(T data)
{
node<T> *p =new node<T>;
p->data =data;

if(first==NULL)
{
first=p;
p->next=first;
p->pre=first;
}
else
{
node<T> *last =first;
while(last->next!=first)
last =last->next;

p->next =last->next;
p->pre =last;
last->next->pre =p;
last->next =p;
last=p;
}
}

template<class T>
void link_1<T>::add_after(T data)
{
node<T> *p =new node<T>;
p->data =data;
node<T> *last = first;
if(first==NULL)
{
cout<<"your list is empty"<<endl;
}
else if(first!=NULL)
{while(last->next!=first)
{
if(last->data ==data)
{p->next =last->next;
p->pre =last;
last->next->pre =p;
last->next =p;
last=p;
}
last=last->next;
cout<<" abhi"<<endl;
}
}
else
{
if(last->data ==data)
{p->next =first;
p->pre =last;
last->next->pre =p;
last->next =p;
}
}
}

template<class T>
void link_1<T>::add_before(T data)
{
node<T> *last =first;
node<T> *p =new node<T>;
if(first==NULL)
cout<<" it is null"<<endl;
else if(first->data ==data && first->next ==first)
{
p->next =first;
first->next =p;
first->pre =p;
p->pre =first;

first =p;
}
else
{
do
{
if(last->next->data ==data)
{p->next =last->next;
p->pre =last;

last->next->pre =p;
last->next =p;
}
last =last->next;
}while(last!=first);
}
}

template<class T>
void link_1<T>::delete_after(T data)
{
node<T> *p;
if(first==NULL)
cout<<" link list is empty"<<endl;
else if(first->data ==data)
cout<<" you have one single node"<<endl;

else
{
node<T> *last =first;
do
{
if(last->data ==data)
{
p=last->next;
p->pre =last;

if(p==first)
first=first->next;
last->next =p->next;
last =p->next->pre;
}
last =last->next;
}while(last!=first);
}
}

template<class T>
void link_1<T>::delete_before(T data)
{
node<T> *last;
node<T> *p;
if(first==NULL)
cout<<" link list is empty"<<endl;
else
{
last=first;
while(last->next!=first)
{
if(last->data ==data)
{
p=last->pre;
last->pre = p->pre;
p->pre->next =p->next;
}
last =last->next;
}
}
}

template<typename T2>
ostream& operator<<(ostream &o,link_1<T2> li)
{
node<T2> *last =li.first;
do
{
o<<" --->"<<last->data;
last =last->next;
}while(last!=li.first);

}
int main()
{
link_1<int> c;
for(int i=0;i<5;i++)
c.create_link_1_list(i);
cout<<c;
int choice;
do
{
cout<<"enter your choice between 1 or 2"<<endl;
cout<<" 1. add data into list"<<endl;
cout<<" 2. add after node"<<endl;
cout<<" 3. add before node"<<endl;
cout<<" 4. delete before"<<endl;
cout<<" 5. delete after "<<endl;
cout<<c;
cout<<endl<<endl;
cin>>choice;
switch(choice)
{
case 1:
int number;
cout<<"enter the data which you want to add"<<endl;
cin>>number;
c.create_link_1_list(number);
cout<<c;
break;
case 2:
int delete_number;
cout<<"enter the data which you want to add after"<<endl;
cin>>delete_number;
c.add_after(delete_number);
cout<<c;
break;
case 3:
int delete_d;
cout<<"enter the data number2 which we add before"<<endl;
cin>>delete_d;
c.add_before(delete_d);
cout<<c;
break;
case 4:
int add_d;
cout<<" enter the data which after you want to delete "<<endl;
cin>>add_d;
c.delete_after(add_d);
cout<<c;
break;
case 5:
int add_b;
cout<<" enter the data which before you want to delete"<<endl;
cin>>add_b;
c.delete_before(add_b);
cout<<c;
break;
}
}while(choice ==1 choice ==2 choice ==choice==4 choice ==5);
return 0;
}

/*

* The Program for hcf & lcm
* */


#include<iostream>
using namespace std;
int hcf(int a,int b)
{
if(a==b)
return b;
else if(a>b)
hcf(a,a-b);
else
hcf(a-b,a);
}

int lcm(int a,int b)
{
if(a==b)
return b;
else if(a<b)
lcm(a+b,a);
else
lcm(a,a+b);
}
int main()
{
int a;
cout<<"enter a value"<<endl;
cin>>a;
int b;
cout<<"enter b value"<<endl;
cin>>b;
cout<<hcf(a,b);
cout<<lcm(a,b);
return 0;
}

/*

* Program for quick sort
* */
#include<iostream>
using namespace std;
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];
a[low]=a[high];
low++;
a[high]=temp;
high--;
}
}while(low<=high);

if(low<last)
quicksort(a,low,last);

if(first<high)
quicksort(a,first,high);
}

int main()
{
int a[20];
for(int i=0;i<19;i++)
a[i]=i;
quicksort(a,1,19);
cout<<a;
return 0;
}

*

* Stack Operation
* Push
* Pop
* Peep
* */

#include<iostream>
using namespace std;
#define size 5
using namespace std;
int top =-1;
int a[5];
void push(int no)
{
if(top==size-1)
cout<<"stack is full"<<endl;
else
a[++top]=no;
}
int pop(int no)
{
if(top==-1)
cout<<"stack is empty"<<endl;
else
return a[top--];
}
void peep()
{
if(top==-1)
cout<<"stack is empty"<<endl;
else
cout<<a[top];
}
int main()
{
cout<<pop(3);
push(5);
peep();
return 0;
}




c++ Program list5

Program list 
 1. Delete node from circular list
 2. Circular link list
 3. Add node from circular link list
 4. Delete the node from circular link list 

/*
* Delete the node
* from circular list
* */


#include<iostream>

using namespace std;
class node
{
public:
int data;
node *next;
};

class circular
{
public:
circular();
void create_list(int data);
void delete_data(int data);
friend ostream& operator<<(ostream& o,circular &c);
node *first;
};
circular::circular()
{
first=NULL;
}
void circular::create_list(int data)
{
node *last;
node *p =new node;
p->data =data;
if(first==NULL)
{
first=p;
p->next =first;
}
else
{
last=first;
while(last->next!=first)
last=last->next;
p->next =first;
last->next =p;
}
}
void circular::delete_data(int data)
{
node *last=first;
node *p;
do
{
if(last->next->data ==data)
{
p=last->next;
last->next =p->next;
if(first==p)
first=first->next;
}
last=last->next;
}while(last!=first);

}
ostream& operator<<(ostream &o,circular &c)
{
node *last =c.first;
do
{
o<<"----->"<<last->data;
last =last->next;
}while(last!=c.first);
}

int main()
{
circular c;
for(int i =1;i<9;i++)
c.create_list(i);
int choice;
do
{
cout<<"enter your choice between 1 or 2"<<endl;
cout<<" 1. add data into list"<<endl;
cout<<" 2. delete node"<<endl;
cout<<c;
cout<<endl<<endl;
cin>>choice;
switch(choice)
{
case 1:
int number;
cout<<"enter the data which you want to add"<<endl;
cin>>number;
c.create_list(number);
cout<<c;
break;
case 2:
int delete_number;
cout<<"enter the data which you want to delete"<<endl;
cin>>delete_number;
c.delete_data(delete_number);
cout<<c;
break;
default:
break;
}
}while(choice ==2 ||choice ==1);

}

/*

* Circular link list
* */

#include<iostream>

using namespace std;

template<class T>
class node
{
public:
T data;
node<T> *next;
};

template<class T>
class circular
{
public:
circular();
void add_node(T data);
node<T> *first;
template<typename T2>
friend ostream& operator<< (ostream& o,circular<T2>& list);
};

template<class T>
circular<T>::circular()
{
first =NULL;
}
template<class T>
void circular<T>::add_node(T data)
{
node<T> *last;
node<T> *p =new node<T>;
p->data =data;
if(first==NULL)
first=p;
else
{
last =first;
while(last->next!=first)
last=last->next;

last->next=p;
first=p;
}
}

template<class T>
ostream& operator << (ostream& o,circular<T>& list)
{
node<T> *last =list.first;
while(last->next!=last)
{
o<<" last--->data "<<last->data;
last =last->next;
}
}

int main()
{
circular<int> c;
for(int i=0;i<5;i++)
c.add_node(i);
cout<<c;
return 0;
}

/*

* Program for circular list:
* 1. Add node before node
* 2. Add node after node
* */

#include<iostream>

using namespace std;

class node
{
public:
int data;
node *next;
};

class circular
{
public:
circular();
void create_list(int data);
void add_before(int data);
void add_after(int data);
friend ostream& operator<<(ostream&o,circular &c);
node *first;
};

circular::circular()
{
first=NULL;
}
void circular::create_list(int data)
{
node *last;
node *p =new node;
p->data =data;
if(first==NULL)
{
first=p;
p->next =first;
}
else
{
last =first;
while(last->next!=first)
last =last->next;
p->next =first;
last->next=p;
}
}
void circular::add_before(int data)
{
cout<<"enter the data"<<endl;
int number;
cin>>number;
node *last =first;
if(first==NULL)
cout<<" the node is empty"<<endl;

else if(first!=NULL)
{
while(last->next!=first)
{
if(last->next->data ==data)
{
node *p =new node;
p->data =number;
p->next =last->next;
last->next=p;
last=p;
}
last=last->next;
}
}
else if(first->data ==data)
{
node *p =new node;
p->data =number;
p->next=first;
last->next =p;
first=p;
}
else
cout<<"No node is present"<<endl;
}
void circular::add_after(int data)
{
node *last =first;
int number;
cout<<"Enter the number which you want to add"<<endl;
cin>>number;
node *p =new node;
p->data =number;

if(first==NULL)
cout<<"no node is present"<<endl;

else if(first!=NULL)
{
while(last->next!=first)
{
if(last->next->data ==data)
{
last =last->next;
p->next =last->next;
last->next =p;
last=p;
}
last =last->next;
}
}
else if(first->data ==data)
{
p->next =first->next;
first->next=p;
first=p;
}

else
cout<<"no node is found"<<endl;
}

ostream& operator<<(ostream& o,circular &c)
{
node *last =c.first;
while(last->next!=c.first)
{
o<<" --->"<<last->data;
last =last->next;
}
return o;
}
int main()
{
circular c;
for(int i=0;i<8;i++)
c.create_list(i);
c.add_before(4);
cout<<c;
c.add_after(6);
cout<<c;
cout<<c;
return 0;
}

c++ Program list4

Program list
1. queue with link list
2. Program for bubble sort
3. Circular list with the delete option
queue with link list

#include<iostream>

using namespace std;


template<class T>
class node
{
public:
T data;
node<T> *next;
};

template<class T>
class queue
{
public:
node<T> *front;
node<T> *rear;
queue();
void add(T data);
int remove();
friend ostream& operator<< <T>(ostream&a,queue<T>& qu);
};

template<class T>
queue<T>::queue()
{
front =NULL;
rear =NULL;
}

template<class T>
void queue<T>::add(T data)
{
node<T> *p =new node<T>;
p->data =data;
p->next =NULL;
if(rear==NULL)
front=rear=p;
else
{
rear->next=p;
rear=rear->next;
}
}
template<class T>
int queue<T>::remove()
{
if(front==NULL)
cout<<"queue is empty"<<endl;
else
{
p=front;
if(front->next!=NULL)
front=front->next;
return p->no;
}
}
template<class T>
ostream& operator<< (ostream& o,queue<T>&q)
{
node<T>* last =q.rear;
while(last!=q.front)
{
o<<q.front->data;
q.front =q.front->next;
}
}

int main()
{
queue<int>a;
for(int i=0;i<5;i++)
a.add(i);
cout<<a;
}

/*

* Program for bubble sort
* */
#include<iostream>

using namespace std;

void bubblesort(int a[],int n)
{
int temp;
for(int i=0;i<n-1;i++)
{
for(int j=0;j<n-i-1;j++)
{
if(a[j]>a[j+1])
{
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
}
int main()
{
int a[5];
cout<<"enter data"<<endl;
for(int i=0;i<5;i++)
cin>>a[i];
bubblesort(a,5);
for(int i=0;i<5;i++)
cout<<a[i]<<" "<<;
return 0;
}

/*

* Circular list with the delete option
*1. delete before
*2. delete after
*/
#include<iostream>

using namespace std;

template<class T>
class node
{
public:
T data;
node *next;
};

template<class T>
class link_list
{
public:
link_list();
void create_link_list_list(T data);
void delete_after(T data);
void delete_before(T data);
node<T> *first;
template<typename T2>
friend ostream& operator<<(ostream&o,link_list<T2> &li);
};

template<class T>
link_list<T>::link_list()
{
first =NULL;
}
template<class T>
void link_list<T>::create_link_list_list(T data)
{
node<T> *last;
node<T> *p =new node<T>;
p->data =data;
if(first==NULL)
{
first=p;
p->next =first;
}
else
{
last =first;
while(last->next!=first)
last =last->next;
p->next =first;
last->next =p;
}
}
template<class T>
void link_list<T>::delete_after(T data)
{
node<T> *last =first;
if(first==NULL)
cout<<" first node is empty"<<endl;
else
{
node<T> *p;
do
{
if(last->data ==data)
{
p=last->next;
last->next =p->next;
if(first==p)
first=first->next;
}
last=last->next;
}while(last!=first);
}
}

template<class T>
void link_list<T>::delete_before(T data)
{
node<T> *last =first;
node<T> *p;
if(first==NULL)
cout<<" first node is empty"<<endl;
else
{
do
{
if(last->next->next->data ==data)
{
p=last->next;
last->next =p->next;
}
last=last->next;
}while(last!=first);
}
if(last->next->next->data ==data)
{
p=first;
p->next =first;
last->next =first;
}
}
template<class T>
ostream& operator<<(ostream &o,link_list<T>& ll)
{node<T> *last =ll.first;
do
{
o<<" --->"<<last->data;
last=last->next;
}while(last!=ll.first);
return o;
}

int main()
{
link_list<int> c;
for(int i =1;i<9;i++)
c.create_link_list_list(i);
cout<<c;
int choice;
do
{
cout<<"enter your choice between 1 or 2"<<endl;
cout<<" 1. add data into list"<<endl;
cout<<" 2. delete after node"<<endl;
\cout<<" 3. delter before node"<<endl;
cout<<c;
cout<<endl<<endl;
cin>>choice;
switch(choice)
{
case 1:
int number;
cout<<"enter the data which you want to add"<<endl;
cin>>number;
c.create_link_list_list(number);
cout<<c;
break;
case 2:
int delete_number;
cout<<"enter the data which you want to delete"<<endl;
cin>>delete_number;
c.delete_after(delete_number);
cout<<c;

break;
case 3:
int delete_d;
cout<<"enter the data number2 which we delter before"<<endl;
cin>>delete_d;
c.delete_before(delete_d);
cout<<c;
break;
default:
break;
}
}while(choice ==2 choice == choice ==3);

}





c++ Program list3

Program list
1. Program to convert octal number
2. Convert decimal to binary
3. Program for reverse number
4. Create link list
5. Stack with link list 

/*

* Program to convert octal number
* */

#include<iostream>

using namespace std;

int main()
{
cout<<"Enter the decimal number"<<endl;
int decimal;
cin>>decimal;
int octal =0;
int a=1;

while(dedcimal>0)
{
int i =decimal%8; //i=4
i =i*a; //i=4
a= a*10; // a=10
octal =octal +i; // i=4
decimal =decimal/8;
}
cout<<"octal --->"<<octal<<endl;
return 0;
}

/*

* Convert decimal to binary
* */

#include<iostream>

using namespace std;

int main()
{
long i;
cout<<"enter the decimal number"<<endl;
int decimal;
cin>>decimal;

int bina=0;
int a=1;
while(decimal>0)
{
i= decimal%2;
i=i*a;
a=a*10;
bina =bina+i;
decimal =decimal/2;
}

cout<<"binary number "<<bina<<endl;
return 0;
}

/*

* Program for reverse number
* */

#include<iostream>

using namespace std;
int main()
{
cout<<"Enter the number"<<endl;
int decimal;
cin>>decimal;
int rev=0;
while(decimal>0)
{
int a=decimal%10;
rev =rev*10+a;
decimal =decimal/10;
}
cout<<"reverse number "<<rev<<endl;
}

link list

#include<iostream>

using namespace std;

template<class T>
class node
{
public:
T data;
node<T> *next;
};
template<class T>
class link_list
{
public:
node<T> *first;
link_list();
void create_link_list(T data);
void new_link_list();
friend ostream& operator<< <T>(ostream &o,link_list<T> &link);
};

template<class T>
link_list<T>::link_list()
{
first =NULL;
}
template<class T>
void link_list<T>::create_link_list( T data)
{
node<T> *last;
node<T> *p =new node<T>;
p->data =data;
p->next =NULL;
if(first ==NULL)
{
first =p;
}
else
{
last =first;
while(last->next!=NULL)
last =last->next;
last->next =p;
}
}
template<class T>
void link_list<T>::new_link_list()
{
node<T> *last =first;
node<T> *t =first;
while(last->next!=NULL)
{
node<T> *p =new node<T>;
p->data =last->data +last->next->data;
last =last->next;
p->next =t->next;
t->next =p;
t=last;
// cerr<<"last"<<last->data<<endl;
node<T> *s =new node<T>;
s->data = last->data - last->next->data;

last =last->next;
s->next =t->next;
t->next =s;

t =last;
}
}

template<class T>
ostream& operator<< ( ostream& o,link_list<T>&list)
{
node<T> *last =list.first;
while(last!=NULL)
{
o<< last->data <<" ----->";
last =last->next;
}
}

int main()
{
link_list<int> a;
for(int i=0;i<5;i++)
a.create_link_list(i);

cout<<a;
a.new_link_list();
cout<<a;
return 0;
}

Stack with link list

#include<iostream>

using namespace std;

template<class T>
class node
{
public:
T data;
node<T> *next;
};

template<class T>
class stack
{
public:
node<T> *top;
stack();
void push(T data);
int pop();
friend ostream& operator<< <T>(ostream& o,stack<T>& stack);
};

template<class T>
stack<T>::stack()
{
top =NULL;
}
template<class T>
void stack<T>::push(T data)
{
node<T> *p =new node<T>;
p->data =data;
p->next =NULL;
if(top ==NULL)
{
top =p;
}
else
{
p->next =top;
top =p;
}
}
template<class T>
int stack<T>::pop()
{
node<T> *p;
if(top ==NULL)
cout<<"stack is empty"<<endl;
else
{
p=top;
top =top->next;
return p->no;
}
}
template<class T>
ostream& operator<< (ostream&o, stack<T>&a)
{
node<T> *last =a.top;
cout<<last->data<<" ---->";
}

int main()
{
stack<int> a;
for(int i=0;i<5;i++)
a.push(i);
cout<<a;
}

Wednesday, July 21, 2010

Virtual Function

A virtual function is a member function of a class, whose functionality can be over-ridden in its derived classes. It is one that is declared as virtual in the base class using the virtual keyword. The virtual nature is inherited in the subsequent derived classes and the virtual keyword need not be re-stated there. The whole function body can be replaced with a new set of implementation in the derived class.

Late Binding

In some programs, it is not possible to know which function will be called until runtime (when the program is run). This is known as late binding (or dynamic binding).

In C++, one way to get late binding is to use function pointers. To review function pointers briefly, a function pointer is a type of pointer that points to a function instead of a variable.

The function that a function pointer points to can be called by using the function call operator (()) on the pointer.

int Add(int nX, int nY)

{return nX + nY;
}
int main()
{// Create a function pointer and make it point to the Add function
    int (*pFcn)(int, int) = Add;
   cout << pFcn(5, 3) << endl; // add 5 + 3
    return 0;
}

Calling a function via a function pointer is also known as an indirect function call.

The following calculator program is functionally identical to the calculator example above, except it uses a function pointer instead of a direct function call

#include <iostream>

using namespace std;
int Add(int nX, int nY)
{return nX + nY;
}
int Subtract(int nX, int nY)
{return nX - nY;
}
int Multiply(int nX, int nY)
{return nX * nY;
}
int main()
{int nX;
cout << "Enter a number: ";
cin >> nX;
int nY;
cout << "Enter another number: ";
cin >> nY;
int nOperation;
do
{
cout << "Enter an operation (0=add, 1=subtract, 2=multiply): ";
cin >> nOperation;
} while (nOperation < 0 ||nOperation > 2);

// Create a function pointer named pFcn (yes, the syntax is ugly)
int (*pFcn)(int, int);
// Set pFcn to point to the function the user chose
switch (nOperation)
{
case 0: pFcn = Add; break;
case 1: pFcn = Subtract; break;
case 2: pFcn = Multiply; break;
}
// Call the function that pFcn is pointing to with nX and nY as parameters

cout << "The answer is: " << pFcn(nX, nY) << endl;
return 0;
}

In this example, instead of calling the Add(), Subtract(), or Multiply() function directly, we’ve instead set pFcn to point at the function we wish to call. Then we call the function through the pointer. The compiler is unable to use early binding to resolve the function call pFcn(nX, nY) because it can not tell which function pFcn will be pointing to at compile time!

Late binding is slightly less efficient since it involves an extra level of indirection. With early binding, the compiler can tell the CPU to jump directly to the function’s address. With late binding, the program has to read the address held in the pointer and then jump to that address. This involves one extra step, making it slightly slower. However, the advantage of late binding is that it is more flexible than early binding, because decisions about what function to call do not need to be made until run time.

In Short
Whenever a program has a virtual function declared, a v - table is constructed for the class. The v-table consists of addresses to the virtual functions forclasses that contain one or more virtual functions.

The object of the class containing the virtual function contains a virtual pointer that points to the base address of the virtual table in memory. Whenever there is a virtual function call, the v-table is used to resolve to the function address.

An object of the class that contains one or more virtual functions contains a virtual pointer called the vptr at the very beginning of the object in the memory. Hence the size of the object in this case increases by the size of the pointer.

This vptr containsthe base address of the virtual table in memory. Note that virtual tables are class specific, i.e., there is only one virtual table for a class irrespective of the number of virtual functions it contains.

This virtual table in turn containsthe base addresses of one or more virtual functions of the class. At the time when a virtual function is called on an object, the vptr of that object provides the base address of the virtual table for that class in memory.

So complier generate the code to extract first two bytes of the object whose address is stored in the pointer
(i.e p =&d)  This gives the address of the VTABLE. The complier also adds a number to this address.

This number is actually an offset in VTABLE. we determine the call.

This table is used to resolve the function call as it contains the addresses of all the virtual functions of that class. This is how dynamic binding is resolved during a virtual function call.

In detail
The virtual table is actually quite simple, though it’s a little complex to describe in words. First, every class
that uses virtual functions (or is derived from a class that uses virtual functions) is given it’s own virtual table.

This table is simply a static array that the compiler sets up at compile time. A virtual table contains one entry for each virtual function that can be called by objects of the class. Each entry in this table is simply a function pointer that points to the most-derived function accessible by that class.

Second, the compiler also adds a hidden pointer to the base class, which we will call *__vptr. *__vptr is set (automatically) when a class instance is created so that it points to the virtual table for that class.

Unlike the *this pointer, which is actually a function parameter used by the compiler to resolve self-references, *__vptr is a real pointer. Consequently, it makes each class object allocated bigger by the size of one pointer.
It also means that *__vptr is inherited by derived classes, which is important.

Ex..

class Base

{
public:
virtual void function1() {};
virtual void function2() {};
};

class D1: public Base
{
public:
virtual void function1() {};
};

class D2: public Base
{
public:
virtual void function2() {};
};

Because there are 3 classes here, the compiler will set up 3 virtual tables: one for Base, one for D1, and one for D2
 
The compiler also adds a hidden pointer to the most base class that uses virtual functions. Although the compiler does this automatically, we’ll put it in the next example just to show where it’s added
 
class Base


{
public:
FunctionPointer *__vptr;
virtual void function1() {};
virtual void function2() {};
};

class D1: public Base
{
public:
virtual void function1() {};
};

class D2: public Base
{
public:
virtual void function2() {};
};

When a class object is created, *__vptr is set to point to the virtual table for that class. For example, when a object of type Base is created, *__vptr is set to point to the virtual table for Base. When objects of type D1 or D2 are constructed, *__vptr is set to point to the virtual table for D1 or D2 respectively.
 
Now, let’s talk about how these virtual tables are filled out. Because there are only two virtual functions here, each virtual table will have two entries (one for function1(), and one for function2()). Remember that when these virtual tables are filled out, each entry is filled out with the most-derived function an object of that class type can call.
 
Base’s virtual table is simple. An object of type Base can only access the members of Base. Base has no access to D1 or D2 functions. Consequently, the entry for function1 points to Base::function1(), and the entry for function2 points to Base::function2().
 
D1’s virtual table is slightly more complex. An object of type D1 can access members of both D1 and Base. However, D1 has overridden function1(), making D1::function1() more derived than Base::function1(). Consequently, the entry for function1 points to D1::function1(). D1 hasn’t overridden function2(), so the entry for function2 will point to Base::function2().
 
D2’s virtual table is similar to D1, except the entry for function1 points to Base::function1(), and the entry for function2 points to D2::function2().





  consider what happens when we create an object of type D1:

int main()

{
D1 cClass;
}

Because cClass is a D1 object, cClass has it’s *__vptr set to the D1 virtual table.

Now, let’s set a base pointer to D1:

int main()

{
D1 cClass;
Base *pClass = &cClass;
}

Note that because pClass is a base pointer, it only points to the Base portion of cClass. However, also note that *__vptr is in the Base portion of the class, so pClass has access to this pointer. Finally, note that pClass->__vptr points to the D1 virtual table! Consequently, even though pClass is of type Base, it still has access to D1’s virtual table.
 
So what happens when we try to call pClass->function1()?
 
int main()

{
D1 cClass;
Base *pClass = &cClass;
pClass->function1();
}

First, the program recognizes that function1() is a virtual function. Second, uses pClass->__vptr to get to D1’s virtual table. Third, it looks up which version of function1() to call in D1’s virtual table. This has been set to D1::function1(). Therefore, pClass->function1() resolves to D1::function1()!
 
Now, you might be saying, “But what if Base really pointed to a Base object instead of a D1 object. Would it still call D1::function1()?”. The answer is no.

int main()


{
Base cClass;
Base *pClass = &cClass;
pClass->function1();
}

In this case, when cClass is created, __vptr points to Base’s virtual table, not D1’s virtual table. Consequently, pClass->__vptr will also be pointing to Base’s virtual table. Base’s virtual table entry for function1() points to Base::function1(). Thus, pClass->function1() resolves to Base::function1(), which is the most-derived version of function1() that a Base object should be able to call.
 
By using these tables, the compiler and program are able to ensure function calls resolve to the appropriate virtual function, even if you’re only using a pointer or reference to a base class!
 
Calling a virtual function is slower than calling a non-virtual function for a couple of reasons: First, we have to use the *__vptr to get to the appropriate virtual table. Second, we have to index the virtual table to find the correct function to call. Only then can we call the function. As a result, we have to do 3 operations to find the function to call, as opposed to 2 operations for a normal indirect function call, or one operation for a direct function call. However, with modern computers, this added time is usually fairly insignificant

Function overloading

Function overloading is a feature of C++ that allows us to create multiple functions with the same name, so long as they have different parameters. Consider the following function:


int Add(int nX, int nY)
{
    return nX + nY;
} 
 
This trivial function adds two integers.  However, what if we also need 
to add two floating point numbers?  This function is not at all 
suitable, as any floating point parameters would be converted to 
integers, causing the floating point arguments to lose their fractional 
values.
 
 int AddI(int nX, int nY)
{
    return nX + nY;
}

double AddD(double dX, double dY)
{
    return dX + dY;
} 
 
However, for best effect, this requires that you define a consistent naming standard, remember the name of all the different flavors of the function, and call the correct one (calling AddD() with integer parameters may produce the wrong result due to precision issues).
Function overloading provides a better solution. Using function overloading, we can declare another Add() function that takes double parameters:

double Add(double dX, double dY)
{
    return dX + dY;
} 
 
We now have two version of Add():

int Add(int nX, int nY); // integer version
double Add(double dX, double dY); // floating point version 
 
Which version of Add() gets called depends on the arguments used in the call — if we provide two ints, C++ will know we mean to call Add(int, int). If we provide two floating point numbers, C++ will know we mean to call Add(double, double). In fact, we can define as many overloaded Add() functions as we want, so long as each Add() function has unique parameters.
Consequently, it’s also possible to define Add() functions with a differing number of parameters:


int Add(int nX, int nY, int nZ)
{
    return nX + nY + nZ;
} 
 
Even though this Add() function has 3 parameters instead of 2, because the parameters are different than any other version of Add(), this is valid.

Note that the function’s return type is NOT considered when overloading functions. Consider the case where you want to write a function that returns a random number, but you need a version that will return an int, and another version that will return a double. You might be tempted to do this:

int GetRandomValue();
double GetRandomValue();

But the compiler will flag this as an error. These two functions have the same parameters (none), and consequently, the second GetRandomValue() will be treated as an erroneous redeclaration of the first.

Consequently, these functions will need to be given different names.

Also keep in mind that declaring a typedef does not introduce a new type — consequently, the following the two declarations of Print() are considered identical:

typedef char *string;
void Print(string szValue);
void Print(char *szValue); 
 
How function calls are matched with overloaded functions
 
Making a call to an overloaded function results in one of three possible outcomes:
 
1) A match is found.  The call is resolved to a particular overloaded function.
 
2)No match is found. The arguments can not be matched to any overloaded function.
 
3)An ambiguous match is found. The arguments matched more than one overloaded function.
 
When an overloaded function is called, C++ goes through the following 
process to determine which version of the function will be called
 
1) First, C++ tries to find an exact match.  This is the case where the 
actual argument exactly matches the parameter type of one of the 
overloaded functions.  For example:
 
void Print(char *szValue);
void Print(int nValue);

Print(0); // exact match with Print(int) 
 
Although 0 could technically match Print(char*), it exactly matches Print(int). 
Thus Print(int) is the best match available.
  
2) If no exact match is found, C++ tries to find a match through promotion

   Char, unsigned char, and short is promoted to an int.
   Unsigned short can be promoted to int or unsigned int, depending on the size of an int
  Float is promoted to double



    Enum is promoted to int

    void Print(char *szValue);
    void Print(int nValue);
    Print('a'); // promoted to match Print(int)
   
   In this case, because there is no Print(char), the char ‘a’ is promoted to an integer, which then matches  Print(int).

3) If no promotion is found, C++ tries to find a match through standard conversion. Standard conversions include:
Any numeric type will match any other numeric type, including unsigned (eg. int to float)

Enum will match the formal type of a numeric type (eg. enum to float)

Zero will match a pointer type and numeric type (eg. 0 to char*, or 0 to float)

A pointer will match a void pointer


void Print(float fValue);
void Print(struct sValue);

Print('a'); // promoted to match Print(float)


Note that all standard conversions are considered equal.
No standard conversion is considered better than any of the others
 
Finally, C++ tries to find a match through user-defined conversion. Although we have not covered classes yet, classes (which are similar to structs) can define conversions to other types that can be implicitly applied to objects of that class. For example, we might define a class X and a user-defined conversion to int.

class X; // with user-defined conversion to int

void Print(float fValue);
void Print(int nValue);

X cValue; // declare a variable named cValue of type class X
Print(cValue); // cValue will be converted to an int and matched to Print(int)

  Function Pointer

 virtual table structure in pure virtual function case 
virtual function FAQ
some more FAQ about virtual
size of class object

1. Where the virtual table reside into memory

2. what will happen if we have virtual keyword in derived class
3. where vpointer will reside into memory/ vptr location
 The precise location of the vptr (the pointer to the class's   
 table of virtual functions' addresses) is implementation-  
 dependent. Some compilers, e.g., Visual C++ and C++   
 Builder, place it offset 0, before the user-declared data   
 members. Other compilers, such as GCC and DEC   
 CXX, place the vptr at the end of the class,   
 after all the user-declared data members. Normally,   
 you wouldn't care about the vptr's position. However, under   
 certain conditions, for example, in applications that dump   
 an object's content to a file so that it can be retrieved   
 afterwards, the vptr's position matters.   
 To detect it, first take the address of an object that.   
 Then compare it to the address of the first data member of   
 that object. If the two addresses are identical, it's likely   
 that the vptr is located at the end. If, however, the   
 member's address is higher than the object's address,   
 this means that the vptr is located at the object's   
 beginning. To detect where your compiler places the vptr,   
 run the following program:  
 class A  
 {  
 public:  
  virtual void f() {}  
  int n;  
 };  
 int main()  
 {  
  A a;  
  char *p1=reinterpret_cast <char *> (&a);  
  char *p2=reinterpret_cast <char *> (&a.n);  
  if (p1==p2)  
  cout<<"vptr is located at the object's   
 end"<<endl;  
  else  
  cout<<"vptr is located at the object's   
 beginning"<<endl;  
 }  

5 . vpointer inherited into the inheritance
6. what  is pure virtual function/abstract class
8. if we create a object of abstract class will we get compile time error or run time error.
  • compile time error
9. can we create a pointer of abstract class
  • Yes
10.  static binding vs dynamic binding
  • Refer 3 question
11. what is Vtable
  • Refer 2 question 
12. Can you tell me where the V table reside into the compile.
  • Refer above question 
13. Can you show the address of Vtable.
  • Refer above question
 14. Can Pure virtual function contain the Vtable.
  • Yes
15. how does Vtable contain the function order for the base and derived class.
  • In base class, The function is defined in same way
  • In derived class, derive class first and than base class
16. Vtable works
  • Refer above question
17. what isVptr
  • Refer above question
18. Does vptr depend  on the class /object
  • each class contain vptr and inherited into derive class
  • vptr is a part of object
19. How many vptr will create if you have three object of the class
  • One vptr
20. Does vptr inherited into derive class
  • Yes
21. what is virtual destructor/need of virtual destructor
22.  virtual destructor Example

 class sample  
 {  
   public:  
   virtual void fun();  
   virtual ~sample()  
 };  
 class der : public sample  
 {  
   public:  
   ~der();  
   void fun();  
 };  
 int main()  
 {  
    sample *p = new derived;  
    delete p;  
 }  
 so it is call the derived class destructor  

22. what is virtual base class/need of virtual class
23. what is memory layout of the virtual base class

24. what is diamond shape problem in case of virtual function.
  • Refer above
25. what is object slicing/need of object slicing
27. can we declare a static function as virtual

28. is it necessary that we should override virtual function

29. Pure virtual function can never a body

30. Does virtual function mechanism work in cosntructor

31, if we do not over ride virtual function in the derived class than will derived class become abstract class.

32. Does  derived class has access to private data member of base

33. Can you base class function from the derived class.

34. what is dreaded diamond

35.what are the access rule  in terms of inheritance. i mean in terms of accessing of variable.

36.  what is final class
       1) make a constructor as private (static function can create a object)

       2) make a destructor as private


      3) 
       class temp
       {
            private:
             ~temp();
             friend final_class;
         };
         class final_class : public virtual temp
         {
               
           }

37.  virtual table unresolved error.
       
       we should define the in the virtual class

38. Does vtable create in the case of pure  virtual function.


39. What is upcasting

40 . what is downcasting.

41. Display VTABLE