Showing posts with label Interview Questions. Show all posts
Showing posts with label Interview Questions. Show all posts

An Challenging Interview question with a difference

The following program is provided:


//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include<iostream>

using namespace
std;

//This class can be designed as you wish
class SR
{

public
:
SR(int i) {}
};


int
main()
{

int
sum = 0;
for
(int i = 1; i < 100; i++)
{

SR ii(i);
while
(i--)
sum += i;
}

cout<<"Expected value of sum = 161700" << endl;
cout<<"Returned value of sum = " << sum << endl;

return
0;
}


As already mentioned above, the expected output of 161700 is provided. The class 'SR' could be written as one wishes. How to do write the class 'SR' to get the desired output?
.
.
.
.
Give it a try before looking at the solution.
.
.
.
.
.
The modified program with the correct 'SR' class as follows:


//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include<iostream>

using namespace
std;

//This class can be designed as you wish
class SR
{

public
:
SR(int& i):ref(i)
{

var = i;
}
~
SR()
{

ref = var;
}

private
:
int
var;
int
&ref;
};


int
main()
{

int
sum = 0;
for
(int i = 1; i < 100; i++)
{

SR ii(i);
while
(i--)
sum += i;
}

cout<<"Expected value of sum = 161700" << endl;
cout<<"Returned value of sum = " << sum << endl;

return
0;
}



Source: Modified from here. Another similar question is available here.

A generic sort program with 'functors' and 'templates'

Picked up this question from here and made a program out of it. It may be a good idea to quickly brush functors and templates if required.

The program sorts the input Vector provided regardless of the type.




//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

using namespace
std;

class
Int
{

public
:
Int() {x_ = 0;}
Int(const int &x) {x_ = x;}
int
getID (void) {return x_;}
int
x_;
};


class
Str
{

public
:
Str() {x_ = "";}
Str(const string &x) {x_ = x;}
string getID (void) {return x_;}
string x_;
};


template
<typename Object> class Comparator {
public
:
bool
operator()(const Object &o1, const Object &o2) const
{

return
(const_cast<Object&>(o1).getID() < const_cast<Object&>(o2).getID());
}


bool
operator()(const Object *o1, const Object *o2) const {
return
(o1->getID() < o2->getID());
}
};


template
<typename VecObject> void Display(VecObject v)
{

VecObject::iterator it;
for
(it = v.begin(); it != v.end(); ++it)
{

cout<<it->getID()<<", ";
}

cout<<endl;
}


int
main()
{

vector<Int> objects1;
objects1.push_back(Int(3));
objects1.push_back(Int());
objects1.push_back(Int(77));

//print the output
cout<<"objects1 before sort = ";
Display(objects1);
std::sort(objects1.begin(), objects1.end(), Comparator<Int> ());
cout<<"objects1 after sort = ";
Display(objects1);

std::vector<Str> objects2;
objects2.push_back(Str("Hello Hello"));
objects2.push_back(Str("apple?"));
objects2.push_back(Str());
objects2.push_back(Str("1 Jump"));

//print the output
cout<<"objects2 before sort = ";
Display(objects2);
std::sort(objects2.begin(), objects2.end(), Comparator<Str> ());
cout<<"objects2 after sort = ";
Display(objects2);

return
0;
}




The output is as follows:

Add two unsigned integers without using '+'

I found this very interesting discussion (and the program) to add two numbers without the use of the arithmetic operator '+'. The obvious guess would be to use the Bitwise operators.

The logic behind the addition operation using the bitwise operators is as follows:


integer1 =  3  = 0011b
integer2 = 5 = 0101b

first operation second operation third operation
0011 0011
shift by one
0101 0101

______ ______
XOR 0110 AND 0001 ------> <<1 0010

Again...
first operation second operation third operation
previous XOR 0110 0110 shift by one
previous <<1 0010 0010
______ ______
XOR 0100 AND 0010 ------> <<1 0100

Again...
first operation second operation third operation
previous XOR 0100 0100 shift by one
previous <<1 0100 0100
______ ______
XOR 0000 AND 0100 ------> <<1 1000

Again...
first operation second operation
previous XOR 0000 0000
previous <<1 1000 1000
______ ______
XOR 1000 AND 0000
When AND iguals 0 the result of XOR is iqual to the sum of the two integers

The program is as follows:



//Program to add two numbers by using boolean operators
//Ref: http://www.daniweb.com/forums/thread84950.html
//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include<iostream>

using namespace
std;

unsigned long
add(unsigned integer1, unsigned integer2)
{

unsigned long
xor, and, temp;

and
= integer1 & integer2; /* Obtain the carry bits */
xor
= integer1 ^ integer2; /* resulting bits */

while
(and != 0 ) /* stop when carry bits are gone */
{

and
<<= 1; /* shifting the carry bits one space */
temp = xor ^ and; /* hold the new xor result bits*/
and
&= xor; /* clear the previous carry bits and assign the new carry bits */
xor
= temp; /* resulting bits */
}

return
xor; /* final result */
}


int
main()
{

int
num1 = 13, num2 = 27;

cout << num1 << " + " << num2 << " = " <<add(num1, num2) << endl;

return
0;
}



The output is:
13 + 27 = 40

See the original discussion here.

Swap two variables without using third and in one line

Couple of weeks back I was interviewing a fresh graduate. Even though they are taught programming, I am not sure if they take it seriously and learn or practice it well. One of the questions I asked was to swap 2 numbers without using a temp variable.

Looking back now, I think it may be a bigger challenge to ask to swap numbers without using a temp variable and in one line. Below are my three different approaches but I would advise you to try it yourself before looking at the answer.


//Program to swap 2 numbers without using 3rd variable and in one line
//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include<iostream>

using namespace
std;

void
approach1(int& a, int& b)
{

cout<<"\nApproach 1"<<endl;
a^=b^=a^=b;
}


void
approach2(int& a, int& b)
{

cout<<"\nApproach 2"<<endl;
//b=(a+b)-(a=b); - This should work but doesnt, why?
a =((a = a + b) - (b = a - b));
}


void
approach3(int& a, int& b)
{

cout<<"\nApproach 3"<<endl;
a = ((a = a * b) / (b = a / b));
}




int
main()
{

int
a = 13, b = 29;
cout<<"\nOriginal"<<endl;
cout<<"a = "<<a<<", b = "<<b<<endl;

approach1(a, b);
cout<<"a = "<<a<<", b = "<<b<<endl;

a = 13, b = 29;
approach2(a, b);
cout<<"a = "<<a<<", b = "<<b<<endl;

a = 13, b = 29;
approach3(a, b);
cout<<"a = "<<a<<", b = "<<b<<endl;

return
0;
}


The output is as follows:
Agreed that the above would be applicable only for integers.

'sizeof' a class

Continuation from last week. What is the sizeof of a class? Wrote a simple program as follows:


//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include<iostream>

using namespace
std;

class
A
{

int
a;
};


class
B
{

int
b;
int
someFunc(void) {return b;}
};


class
C
{

void
someFunc1(void) {};
void
someFunc2(void) {};
};


class
D : public A
{

void
someFunc(void) {};
};



int
main()
{

cout<<"Size of class A = "<<sizeof(A)<<endl;
cout<<"Size of class B = "<<sizeof(B)<<endl;
cout<<"Size of class C = "<<sizeof(C)<<endl;
cout<<"Size of class D = "<<sizeof(D)<<endl;
}



The output is as follows:

After finishing this, I found this interesting article here.

Checking the 'sizeof' doubts

I noticed sometime back that one of my programs behaved unexpectedly in certain scenarios which was traced to an incorrect use of sizeof. As a result, I made a small program to make sure that my understanding of sizeof is correct. Here is the program:



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include<iostream>

using namespace
std;

int
main()
{

char
a[]="";
cout<<"Size of a[] = "<<sizeof(a)<<endl;

char
b[]=" ";
cout<<"Size of b[ ] = "<<sizeof(b)<<endl;

char
c[10];
cout<<"Size of c[10] = "<<sizeof(c)<<endl;

char
* d;
cout<<"Size of d = "<<sizeof(d)<<endl;

char
* e = c;
cout<<"Size of e = "<<sizeof(e)<<endl;

char
f[] = "123456";
cout<<"Size of f = "<<sizeof(f)<<endl;

char
g[] = {'1','2','3','4','5','6'};
cout<<"Size of g = "<<sizeof(g)<<endl;

return
0;
}



The output is as follows:
A lot of interviewers love the sizeof questions.

Have you come across any interesting sizeof problems? Please feel free to add them in comments.

String Shift and Print

After my last blog post, someone pointed out a similar problem here. The problem goes:

Write a program that generates from the string "abcdefghijklmnopqrstuvwxyz{" the following:
a
bcb
cdedc
defgfed
efghihgfe
fghijkjihgf
ghijklmlkjihg
hijklmnonmlkjih
ijklmnopqponmlkji
jklmnopqrsrqponmlkj
klmnopqrstutsrqponmlk
lmnopqrstuvwvutsrqponml
mnopqrstuvwxyxwvutsrqponm
nopqrstuvwxyz{zyxwvutsrqpon

Well there is no time limit this time and we dont even need to use google. I think this is slightly trickier than the last one.

Here is my solution:



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy

#include<iostream>
#include<string>

using namespace
std;

int
main()
{

string str = "abcdefghijklmnopqrstuvwxyz{";
unsigned
strlen = str.length();
string tempStr;
int
loop = 0;
while
(tempStr.length() < strlen)
{

int
start1 = loop;
int
count1 = loop + 1;
tempStr = str.substr(start1,count1);

count1--;
for
(; count1 > 0; count1--)
tempStr.append(str.substr(start1+count1-1, 1));

cout<<tempStr;
cout<<endl;
loop++;
}

return
0;
}




ASCII Print

Few weeks back, someone I know got asked the following question in an interview:

Write a C++ program in 15 minutes to print the following in the output:
a
bcb
cdedc
defgfed
efghihgfe
fghijkjihgf
ghijklmlkjihg
hijklmnonmlkjih
ijklmnopqponmlkji
jklmnopqrsrqponmlkj
klmnopqrstutsrqponmlk
lmnopqrstuvwvutsrqponml
mnopqrstuvwxyxwvutsrqponm
nopqrstuvwxyz{zyxwvutsrqpon

You can do search on the web for any information but all your searches would be logged and used to assess your answer.

Well my obvious guess would be to take help of ASCII table. My only search was for Ascii table in google. I did try and make it in less than 15 mins. My solution is below but do try it on your own before looking at my solution.


//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include<iostream>
#include<string>

using namespace
std;

int
main()
{

char
c=(char)97; //'a' in ASCII
char loop = 0;
while
(c <= 'n')
{

char
x = 0;
for
(; x <=loop; x++)
{

cout<<char(c+x);
}

for
(char y = 1; y < x; y++)
{

cout<<char(c+x-y-1);
}

cout<<endl;
c++;
loop++;
}


return
0;
}



Difference between Deep copy and Shallow copy in C++

So what is the difference between 'Deep copy' (sometimes referred to as 'Hard copy') and 'Shallow copy' in C++

Shallow copy: Copies the member values from one object into another.

Deep Copy: Copies the member values from one object into another. Any pointer objects are duplicated and Deep Copied.

There are some interesting discussions on Stack Overflow here and here. A related discussions here is interesting as well.

Program to demonstrate as follows:


//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include<iostream>
#include<string>

using namespace
std;

class
MyString
{

public
:
MyString(){}
MyString(string str)
{

size = str.size();
data = new char(size+1); //+1 for '\0'
memcpy(data, str.c_str(), size+1);
}

//MyString(const MyString& copy); - Use default for Shallow
void DeepCopy(const MyString& copy) //Deep Copy
{
size = copy.size;
data = new char(size+1); //+1 for '\0'
memcpy(data, copy.data, size+1);
}

int
size;
char
* data;
};


int
main()
{

MyString m1("Zahid");
cout<<"\nm1.size = "<<m1.size<<", &m1.data = "<<(void *)m1.data<<", *m1.data = "<<m1.data<<endl;

MyString m2(m1); //Uses the default copy constructor - Shallow Copy
cout<<"\nm2.size = "<<m2.size<<", &m2.data = "<<(void *)m2.data<<", *m2.data = "<<m2.data<<endl;

MyString m3; //Another default constructor
m3.DeepCopy(m1);
cout<<"\nm3.size = "<<m3.size<<", &m3.data = "<<(void *)m3.data<<", *m3.data = "<<m3.data<<endl;

return
0;
}


Output as follows:


Difference between 'new', 'new operator' and 'operator new' in C++

A question asked in a forum said:

Why does void* p = new (1024); gives me a compilation error while void* p = operator new (1024); works. What is the difference between new and "operator new"?

Lets go back to the beginning. Once upon a time there was this C language that used 'malloc' to allocate memory. Then when C++ came, a new way was defined of allocating memory by the use of 'new'. Its supposed to be much safter and better way but some software gurus may differ. Memory for 'new' is allocated from 'Free Store' and memory by 'malloc' is generated from 'heap'. The 'heap' and 'Free Store' may be the same area and is a compiler implementation detail.

The syntax for 'operator new' is:
void* new (std::size_t size);

All it does is allocate a memory of size specified

On the other hand, 'new' does 2 things:
1. It calls 'operator new'
2. It calls constructor for the type of object

In the above case since 1024 is not a type, it will fail in calling its constructor.

'new' is also referred to as 'keyword new' or 'new operator' to cause more confusion :)

Here is a small example to play with 'operator new' after the example you will realise that regardless of what is passed, it always allocates a 4 byte memory.



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include<iostream>

using namespace
std;

int
main()
{

//void* p = new (1024);

void
* p = operator new (1024);

//Lets test if we can do anything with the memory
cout<<"p = "<<p<<endl;
cout<<"sizeof(p) = "<<sizeof(p)<<endl;
int
*x = static_cast<int *>(p);
cout<<"*x before = "<<*x<<endl;
*
x = 23456;
cout<<"*x after = "<<*x<<endl;

void
* q = operator new (0);
cout<<"\nq = "<<q<<endl;
cout<<"sizeof(q) = "<<sizeof(q)<<endl;
x = static_cast<int *>(q);
cout<<"*x before = "<<*x<<endl;
*
x = 65432;
cout<<"*x after = "<<*x<<endl;

void
* z = operator new ('a');
cout<<"\nz = "<<z<<endl;
cout<<"sizeof(z) = "<<sizeof(z)<<endl;
x = static_cast<int *>(z);
cout<<"*x before = "<<*x<<endl;
*
x = 11111;
cout<<"*x after = "<<*x<<endl;

return
0;
}


The output is as follows:


My knowledge in this area is quite limited so please feel free to improve on my explanation or correct it.

Challenging problem to test your 'for loop' basics

While scouting through the web I came across this fun puzzle:

In the following code:


#include<iostream>

using namespace
std;

int
main()
{

int
i, n = 20;
for
(i=0; i<n; i--)
{

cout << "x" << endl;
}


return
0;
}




by changing only ONE character in the above code, meaning you cannot change 20 to 31, because you will have changed two characters, you can change 20 to 21, because you only changed the 0, do the following:

find 3 ways to make the above code print x 20 times (by changing only one character).


Give it a try, if you can do it then look at the answer below.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
The first one should be simple:
i-- becomes n--
.
.
.
.
.
.
.
I guess this is the second one you got
i<n becomes i+n
.
.
.
.
.
.
.
.
.
.
The third one which is tricky, In fact there are two similar solutions is:

i<n becomes, -i<n,
i
<n becomes, ~i<n

remember BODMAS


Class initialisation and constructors

There is often lots of confusion with regards to class initialisation. People may forget to take care while using default constructors and copy constructors. Here is a simple example that tries to explain lots of concepts.





//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//This program gives an example of constructors and initialisations

#include<iostream>

using namespace
std;

//Example of a class
class someClass1
{

public
:
//implicit default constructor
int x;
int
*y;
};


//Example of a class with constructor
class someClass2
{

public
:
someClass2(const someClass2& xyz)
{

cout<<"** copy constructor called"<<endl;
x = xyz.x;
y = new int(*xyz.y);
}

//default constructor will have to be explicitly defined
someClass2() {};
//overloading operator '='
const someClass2& operator = (const someClass2& xyz)
{

cout<<"** operator '=' called"<<endl;
x = xyz.x;
y = new int(*xyz.y);
return
*this;
}

int
x;
int
*y;
};


int
main()
{

someClass1 a; //Default initialisation
a.x = 1234;
a.y = new int(6789);

cout<<"someClass1: a.x = "<<a.x<<" a.y( " <<a.y<< " ) = "<<*(a.y)<<endl;

someClass1 b = a; //Copy Initialisation

cout<<"someClass1: b.x = "<<b.x<<" b.y( " <<b.y<< " ) = "<<*(b.y)<<endl;

someClass1 c(a); //Direct Initialisation

cout<<"someClass1: c.x = "<<c.x<<" c.y( " <<c.y<< " ) = "<<*(c.y)<<endl;

//Calling default constructor
someClass2 aa;
aa.x = 2468;
aa.y = new int(3579);

cout<<"someClass2: aa.x = "<<aa.x<<" aa.y( " <<aa.y<< " ) = "<<*(aa.y)<<endl;

//calling copy constructor
someClass2 bb = aa; //Copy Initialisation - note copy constructor will be called

cout<<"someClass2: bb.x = "<<bb.x<<" bb.y( " <<bb.y<< " ) = "<<*(bb.y)<<endl;

//calling copy constructor
someClass2 cc(aa); //Direct Initialisation - note copy constructor called in this case as well

cout<<"someClass2: cc.x = "<<cc.x<<" cc.y( " <<cc.y<< " ) = "<<*(cc.y)<<endl;

someClass2 dd;
//calling operator =
dd = aa;

cout<<"someClass2: dd.x = "<<dd.x<<" dd.y( " <<dd.y<< " ) = "<<*(dd.y)<<endl;

return
0;
}







The output is as follows:

There are certain things worth noting in the above example:
  • In case of someClass1, since only the default constructor is used, the same pointer is used for y in all the cases. This can cause serious problems in the code if one of the classes delete the memory pointed by y for class someClass1. This problem is not present in someClass2
  • If any constructor is defined, it becomes necessary to define the default constructor. You can make sure that nobody uses default constructor in case of someClass2 by making it private (I havent done that because I wanted to show operator =)
  • As you can see in case of variable cc, copy constructor would always be called instead of operator =.
  • operator = would only be called in case of assignment. This is a common mistake.
  • In the code above, cc(aa) is better than using bb = aa even though the results are the same. The main advantage being that it will avoid confusion with operator '=' if its overloaded for a novice and the constructor can be overloaded to take more than one input in future.

Interesting Challenging problem on Code Complexity

Picked up this interesting problem from the following book:



How many execution paths can this simple three line code take:



String EvaluateSalaryAndReturnName( Employee e )
{

if
( e.Title() == "CEO" || e.Salary() > 100000 )
{

cout << e.First() << " " << e.Last() << " is overpaid" << endl;
}

return
e.First() + " " + e.Last();
}






The answer may surprise you. I have embedded the actual pages from Google books. Luckily the whole problem and solution is given. See Item 18.

Interview Question on the Slicing Problem

Someone was talking about the Slicing Problem with classes in one of the companies we do projects for. As the name states, the Slicing problem arises when a part of the class is Sliced away. This will happen when derived class is assigned to the base class. Here is a simple example that is also been used for interviews:



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include<iostream>

using namespace
std;

class
Parent
{

public
:
virtual
void func_a(void);
};


class
Child : public Parent
{

public
:
void
func_a(void);
};


void
func_1(Parent p);
void
func_2(Parent* p);
void
func_3(Parent& p);


int
main()
{

//Using the Parent class
Parent p;
cout<<"\nParent Class"<<endl;
func_1(p);
func_2(&p);
func_3(p);

//Using the Child class
Child c;
cout<<"\n\nChild Class"<<endl;
func_1(c);
func_2(&c);
func_3(c);

//Using the Parent class that is initialised to class
Parent p2 = c; //Note that in p2, additional info about c would be lost
cout<<"\n\nParent p2 Class"<<endl;
func_1(p2);
func_2(&p2);
func_3(p2);

//Not possible to initialise directly from base to derived class.
//Child c2 = p2; - ERROR: cannot convert from 'Parent' to 'Child'
//The way round it would be to have a constructor or overload operator =

return
0;
}


void
Parent::func_a()
{

cout<<"Parent::func_a()"<<endl;
}


void
Child::func_a(void)
{

cout<<"Child::func_a()"<<endl;
}


void
func_1(Parent p)
{

cout<<"func_1 -> ";
p.func_a();
}


void
func_2(Parent* p)
{

cout<<"func_2 -> ";
p->func_a();
}


void
func_3(Parent& p)
{

cout<<"func_3 -> ";
p.func_a();
}





The output is as follows:

What is the output of this tricky program?

Interesting problem from C Programming tricks:



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include<iostream>

using namespace
std;

int
main()
{

int
a=2,*f1,*f2;
f1=f2=&a;
*
f2+=*f2+=a+=2.5;
*
f1+=*f1+=a+=2.5;
cout<<"a = "<<a<<" *f1 = "<<*f1<<" *f2 = "<<*f2<<endl;

return
0;
}






What is the final value of a, *f1 and *f2. Choose one from below:
a) 18,18,18
b) 10,10,10
c) 72,72,72
d) 64,64,64
e) 26,26,26

The answer is...
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.


A Macro Pitfall Question

Assuming that two macros are defined in the following way
#define max1(a,b) a < b ? b : a
#define max2(a,b) (a) < (b) ? (b) : (a)

what would be the value of x in the following cases:
x = max1(i += 3, j);
x = max2(i += 3, j);

and why?

Assume that initial value of i = 5 and j = 7 in both the cases. What is the value of i and j after the Macro?

Answer:
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
In case of max1, x = 12, i = 12 and j = 7. The reason being the substitution will happen like this:
i += 3 < j ? j : i += 3
which using operator precedence rules and language rules means:
i += ((3 < j) ? j : i += 3). Since 3 < 7, i = i + j = 12 which is the same as x.

In case of max2, x = 11, i = 11 and j = 7. The reason being the substitution will happen like this:
(i += 3) < (j) ? (j) : (i += 3). Since 5+3 = 8 which is > 7, i+=3 will be executed again (2nd time) so 5+6 = 11 which is the value of i and x.

Functions returning void

C++ truths discusses an interesting interview question:

"Can you write a return statement in a function that returns void?" The answer is "Yes! You can return void!"

The following is a simple program picked up from the same blog and modified showing a function returning void



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//This is a simple example of a function returning void
#include<iostream>

using namespace
std;

static
void foo (void)
{

cout<<"foo() called"<<endl;
}

static
void bar (void)
{

cout<<"bar() called"<<endl;
return
foo(); // Note this return statement.
}
int
main ()
{

cout<<"main() called"<<endl;
bar();
return
0;
}


The output is as follows:

This feature is very useful in case of Templates. Lets write a simple program that uses Templates:


//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//This is a simple example of a Template returning void
#include<iostream>
//#include <typeinfo> - Some compilers may need this

using namespace
std;

template
<class T> T FOO (void)
{

cout<<"T FOO() called with T = "<<typeid(T).name()<<endl;
return
T(); // Default construction
}

template
<class T> T BAR (void)
{

cout<<"T BAR() called with T = "<<typeid(T).name()<<endl;
return
FOO<T>(); // Syntactic consistency. Same for int, void and everything else.
}

int
main (void)
{

cout<<"main() called"<<endl;
BAR<void>();
BAR<int>();
BAR<char>();
}



The output is as follows:

Example of C++ class invariant

According to Bjarne Stroustrup in 'The C++ Programming Language':

The values of the members and the objects referred to by members are collectively called the state of the object (or simply, its value). A major concern of a class design is to get an object into a well defined state (initialization/construction), to maintain a well defined state as operations are performed, and finally to destroy the object gracefully. The property that makes the state of an object well-defined is called its invariant.

Thus, the purpose of initialization is to put an object into a state for which the invariant holds. Typically, this is done by a constructor. Each operation on a class can assume it will find the invariant true on entry and must leave the invariant true on exit. The destructor finally invalidates the invariant by destroying the object.

Another way of writing the same thing:

A class invariant is a condition that defines all valid states for an object. It is a logical condition to ensure the correct working of a class. Class invariants must hold when an object is created, and they must be preserved under all operations of the class. In particular all class invariants are both preconditions and post-conditions for all operations or member functions of the class.

The conditions that have to be met for a condition to be an invariant of the class are:
=> The condition should hold at the end of every constructor.
=> The condition should hold at the end of every mutator (non-const) operation.

Lets look at an example. Suppose we are designing a system where the user input some pressure to be applied. The pressure can be between 30 and 100 units. A user should not be allowed to put pressure outside these bounds:


//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Example of class invariant
#include<iostream>

using namespace
std;

const
int PressureOverflow = 1;
const
int PressureUnderflow = 2;

const
int MIN_PRESSURE = 30;
const
int MAX_PRESSURE = 100;

class
Pressure
{

public
:
Pressure();
void
setPressure(int p);
void
displayPressure(void) const;
private
:
int
pressureMonitor; //invariant
};

Pressure::Pressure()
{

pressureMonitor = 30;
}


void
Pressure::setPressure(int p)
{

try

{

if
(p < MIN_PRESSURE)
throw
PressureUnderflow;
if
(p > MAX_PRESSURE)
throw
PressureOverflow;
pressureMonitor = p;
}

catch
(int pError)
{

switch
(pError)
{

case
PressureUnderflow:
pressureMonitor = MIN_PRESSURE;
cout<<"ERROR: Pressure should be between "<<MIN_PRESSURE<<" and "<<
MAX_PRESSURE<<" - Value set to "<<pressureMonitor<<endl;
break
;
case
PressureOverflow:
pressureMonitor = MAX_PRESSURE;
cout<<"ERROR: Pressure should be between "<<MIN_PRESSURE<<" and "<<
MAX_PRESSURE<<" - Value set to "<<pressureMonitor<<endl;
break
;
default
:
break
;
}
}
}


void
Pressure::displayPressure(void) const
{

cout<<"Current Pressure set to: "<<pressureMonitor<<endl;
}


int
main()
{

Pressure p;
int
x=0;
while
(1)
{

p.displayPressure();
cout<<"Enter new Pressure: ";
cin>>x;
p.setPressure(x);
}


return
0;
}


The output is as follows:

Check out this stream