C++ Technical Apti Notes
C++ Technical Apti Notes
class Test
{
static int i;
int j;
};
int Test::i;
int main()
{
cout << sizeof(Test);
return 0;
}
Output: 4 (size of integer)
static data members do not contribute in size of an object. So ‘i’ is not considered in
size of Test. Also, all functions (static and non-static both) do not contribute in size.
#include<iostream>
class Base2 {
public:
Base2()
{ cout << "Base2's constructor called" << endl; }
};
int main()
{
Derived d;
return 0;
}
Output:
Base1’s constructor called
Base2’s constructor called
Derived’s constructor called
In case of Multiple Inheritance, constructors of base classes are always called in
derivation order from left to right and Destructors are called in reverse order.
Output of C++ Program | Set 2
Predict the output of below C++ programs.
Question 1
#include<iostream>
using namespace std;
class A {
public:
A(int ii = 0) : i(ii) {}
void show() { cout << "i = " << i << endl;}
private:
int i;
};
class B {
public:
B(int xx) : x(xx) {}
operator A() const { return A(x); }
private:
int x;
};
void g(A a)
{ a.show(); }
int main() {
B b(10);
g(b);
g(20);
getchar();
return 0;
}
Output:
i = 10
i = 20
#include<iostream>
using namespace std;
class base {
int arr[10];
};
int main(void)
{
cout<<sizeof(derived);
getchar();
return 0;
}
Output: If integer takes 4 bytes, then 80.
Since b1 and b2 both inherit from class base, two copies of class base are there in
class derived. This kind of inheritance without virtual causes wastage of space and
ambiguities. virtual base classes are used to save space and avoid ambiguities in
such cases. For example, following program prints 48. 8 extra bytes are for
bookkeeping information stored by the compiler (See this for details)
#include<iostream>
using namespace std;
class base {
int arr[10];
};
int main(void)
{
cout<<sizeof(derived);
getchar();
return 0;
}
Call by address
Int main()
Int a,b;
Func(&a,&b); //call
*x
*y //use
Call by reference
Int main()
Int a,b;
Func(a,b); //call
X;
Y; //use
Return( (x>y)?x:y);
Return( (x>y) ? x : y );
For example, the following tells the compiler that feet is another name for int −
typedef int feet;
Now, the following declaration is perfectly legal and creates an integer variable called
distance −
feet distance;
• cout<<” ”;
cout is a predefined object that represents the standard output stream in C++. Here,
the standard output stream represents the screen.
The operator << is called the insertion or put to operator. It inserts (or sends) the
contents of the variable on its right to the object on its left.
• Encapsulation: The wrapping up of data and functions into a single unit (called class)
is known as encapsulation. The data is not accessible to the outside world, and only
those functions which are wrapped in the class can access it.
• Abstraction: Abstraction refers to the act of representing essential features without
including the background details or explanations.
• cin>>_;
cin is a predefined object that represents the standard input stream in C++. Here, the
standard input stream represents the keyboard.
The operator >> is called the extraction or get from operator. It extracts (or takes)
the value from the keyboard and assigns it to the variable on its left.
• Cascading: The multiple use of << in one statement is called cascading.
• A program can have same name for local and global variables, but value of local
variable inside a function will take preference.
• #include <iostream>
• using namespace std;
•
• // Global variable declaration:
• int g = 20;
• int main () {
• // Local variable declaration:
• int g = 10;
•
• cout << g;
•
• return 0;
• }
Output: 10
Output of C++ Program | Set 3
Predict the output of below C++ programs.
Question 1
#include<iostream>
class Q : public P {
public:
void print()
{ cout <<" Inside Q"; }
};
class R: public Q {
};
int main(void)
{
R r;
r.print();
return 0;
}
Output:
Inside Q
#include<iostream>
#include<stdio.h>
using namespace std;
class Base
{
public:
Base()
{
fun(); //note: fun() is virtual
}
virtual void fun()
{
cout<<"\nBase Function";
}
};
int main()
{
Base* pBase = new Derived();
delete pBase;
return 0;
}
Output:
Base Function
When a virtual function is called directly or indirectly from a constructor (including
from the mem-initializer for a data member) or from a destructor, and the object to
which the call applies is the object under construction or destruction, the function
called is the one defined in the constructor or destructor’s own class or in one of its
bases, but not a function overriding it in a class derived from the constructor or
destructor’s class, or overriding it in one of the other base classes of the most derived
object.
Because of this difference in behavior, it is recommended that object’s virtual function
is not invoked while it is being constructed or destroyed.
Output of C++ Program | Set 4
Predict the output of below C++ programs.
Question 1
#include<iostream>
using namespace std;
int x = 10;
void fun()
{
int x = 2;
{
int x = 1;
cout << ::x << endl;
}
}
int main()
{
fun();
return 0;
}
Output: 10
If Scope Resolution Operator is placed before a variable name then the global variable
is referenced. So if we remove the following line from the above program then it will
fail in compilation.
int x = 10;
Question 2
#include<iostream>
using namespace std;
class Point {
private:
int x;
int y;
public:
Point(int i, int j); // Constructor
};
Point::Point(int i = 0, int j = 0) {
x = i;
y = j;
cout << "Constructor called";
}
int main()
{
Point t1, *t2;
return 0;
}
Output: Constructor called.
If we take a closer look at the statement “Point t1, *t2;:” then we can see that only one
object is constructed here. t2 is just a pointer variable, not an object.
Question 3
#include<iostream>
using namespace std;
class Point {
private:
int x;
int y;
public:
Point(int i = 0, int j = 0); // Normal Constructor
Point(const Point &t); // Copy Constructor
};
Point::Point(int i, int j) {
x = i;
y = j;
cout << "Normal Constructor called\n";
}
int main()
{
Point *t1, *t2;
t1 = new Point(10, 15);
t2 = new Point(*t1);
Point t3 = *t1;
Point t4;
t4 = t3;
return 0;
}
Output:
Normal Constructor called
Copy Constructor called
Copy Constructor called
Normal Constructor called
class Test {
int value;
public:
Test(int v);
};
Test::Test(int v) {
value = v;
}
int main() {
Test t[100];
return 0;
}
Output:
Compiler error
The class Test has one user defined constructor “Test(int v)” that expects one
argument. It doesn’t have a constructor without any argument as the compiler doesn’t
create the default constructor if user defines a constructor. Following modified
program works without any error.
#include<iostream>
using namespace std;
class Test {
int value;
public:
Test(int v = 0);
};
Test::Test(int v) {
value = v;
}
int main() {
Test t[100];
return 0;
}
Does C++ compiler create default constructor when we write our
own?
In C++, compiler by default creates default constructor for every class. But, if we
define our own constructor, compiler doesn’t create the default constructor.
For example, program 1 compiles without any error, but compilation of program 2 fails
with error “no matching function for call to `myInteger::myInteger()’ ”
Program 1
#include<iostream>
using namespace std;
class myInteger
{
private:
int value; //...other things in class
};
int main()
{
myInteger I1;
getchar();
return 0;
}
Program 2
#include<iostream>
using namespace std;
class myInteger
{
private:
int value;
public:
myInteger(int v) // parametrized constructor
{ value = v; }
//...other things in class
};
int main()
{
myInteger I1;
getchar();
return 0;
}
Question 2
#include<iostream>
using namespace std;
int &fun() {
static int a = 10;
return a;
}
int main() {
int &y = fun();
y = y +30;
cout<<fun();
return 0;
}
Output:
40
The program works fine because ‘a’ is static. Since ‘a’ is static, memory location of it
remains valid even after fun() returns. So a reference to static variable can be
returned.
Question 3
#include<iostream>
using namespace std;
class Test
{
public:
Test();
};
Test::Test() {
cout<<"Constructor Called \n";
}
int main()
{
cout<<"Start \n";
Test t1(); //Test t1; would have called the constructor
cout<<"End \n";
return 0;
}
Output:
Start
End
Note that the line “Test t1();” is not a constructor call. Compiler considers this line as
declaration of function t1 that doesn’t receive any parameter and returns object of
type Test.
Output of C++ Program | Set 6
Predict the output of below C++ programs.
Question 1
#include<iostream>
class Test {
int value;
public:
Test (int v = 0) {value = v;}
int getValue() { return value; }
};
int main() {
const Test t;
cout << t.getValue();
return 0;
}
Output: Compiler Error.
A const object cannot call a non-const function. The above code can be fixed by either
making getValue() const or making t non-const. Following is modified program with
getValue() as const, it works fine and prints 0.
#include<iostream>
class Test {
int value;
public:
Test (int v = 0) { value = v; }
int getValue() const { return value; }
};
int main() {
const Test t;
cout << t.getValue();
return 0;
}
Question 2
#include<iostream>
class Test {
int &t;
public:
Test (int &x) { t = x; }
int getT() { return t; }
};
int main()
{
int x = 20;
Test t1(x);
cout << t1.getT() << " ";
x = 30;
cout << t1.getT() << endl;
return 0;
}
Output: Compiler Error
Since t is a reference in Test, it must be initialized using Initializer List. Following is the
modified program. It works and prints “20 30”.
#include<iostream>
class Test {
int &t;
public:
Test (int &x):t(x) { }
int getT() { return t; }
};
int main() {
int x = 20;
Test t1(x);
cout << t1.getT() << " ";
x = 30;
cout << t1.getT() << endl;
return 0;
}
Output of C++ Program | Set 7
Predict the output of following C++ programs.
Question 1
class Test1 {
int y;
};
class Test2 {
int x;
Test1 t1;
public:
operator Test1() { return t1; }
operator int() { return x; }
};
int main() {
Test2 t;
fun(t);
return 0;
}
Output: Compiler Error
There are two conversion operators defined in the Test2 class. So Test2 objects can
automatically be converted to both int and Test1. Therefore, the function call fun(t) is
ambiguous as there are two functions void fun(int ) and void fun(Test1 ), compiler has no way
to decide which function to call. In general, conversion operators must be overloaded carefully
as they may lead to ambiguity.
Question 2
#include <iostream>
using namespace std;
class X {
private:
static const int a = 76;
public:
static int getA() { return a; }
};
int main() {
cout <<X::getA()<<endl;
return 0;
}
Output: The program compiles and prints 76
Generally, it is not allowed to initialize data members in C++ class declaration, but static const
integral members are treated differently and can be initialized with declaration.
Output of C++ Program | Set 8
Predict the output of following C++ programs.
Question 1
#include<iostream>
using namespace std;
class Test1
{
int x;
public:
void show() { }
};
class Test2
{
int x;
public:
virtual void show() { }
};
int main(void)
{
cout<<sizeof(Test1)<<endl;
cout<<sizeof(Test2)<<endl;
return 0;
}
Output:
4
8
There is only one difference between Test1 and Test2. show() is non-virtual in Test1,
but virtual in Test2. When we make a function virtual, compiler adds an extra pointer
vptr to objects of the class. Compiler does this to achieve run time polymorphism. The
extra pointer vptr adds to the size of objects, that is why we get 8 as size of Test2.
Question 2
#include<iostream>
using namespace std;
class P
{
public:
virtual void show() = 0;
};
class Q : public P {
int x;
};
int main(void)
{
Q q;
return 0;
}
Output: Compiler Error
We get the error because we can’t create objects of abstract classes. P is an abstract
class as it has a pure virtual method. Class Q also becomes abstract because it is
derived from P and it doesn’t implement show().
#include<iostream>
using namespace std;
class P
{
public:
virtual void show() = 0;
};
class Q : public P {
public:
int x;
void show()
{
cout<<"Hurray!!";
}
};
int main(void)
{
Q q;
q.show();
return 0;
}
The pure virtual class in the base class has to be overridden in derived class.
Output of C++ Program | Set 9
Predict the output of following C++ programs.
Question 1
template <class S, class T> class Pair
{
private:
S x;
T y;
/* ... */
};
int main ()
{
Pair <Element<int>, Element<char>> p;
return 0;
}
Output:
Compiler Error: '>>' should be '> >' within a nested template argument
list
When we use nested templates in our program, we must put a space between two
closing angular brackets, otherwise it conflicts with operator >>. For example,
following program compiles fine.
template <class S, class T> class Pair
{
private:
S x;
T y;
/* ... */
};
int main ()
{
Pair <Element<int>, Element<char> > p; // note the space between '>'
and '>'
return 0;
}
Question 2
#include<iostream>
using namespace std;
class Test
{
private:
static int count;
public:
static Test& fun();
};
int Test::count = 0;
Test& Test::fun()
{
Test::count++;
cout<<Test::count<<" ";
return *this;
}
int main()
{
Test t;
t.fun().fun().fun().fun();
return 0;
}
Output:
Compiler Error: 'this' is unavailable for static member functions
this pointer is not available to static member methods in C++, as static methods can
be called using class name also. Similarly in Java, static member methods cannot
access this and super (super is for base or parent class).
If we make fun() non-static in the above program, then the program works fine.
#include<iostream>
using namespace std;
class Test
{
private:
static int count;
public:
Test& fun(); // fun() is non-static now
};
int Test::count = 0;
Test& Test::fun()
{
Test::count++;
cout<<Test::count<<" ";
return *this;
}
int main()
{
Test t;
t.fun().fun().fun().fun();
return 0;
}
Output:
Output:
1 2 3 4
#include<iostream>
#include<string.h>
using namespace std;
class String
{
char *p;
int len;
public:
String(const char *a);
};
int main()
{
String s1("Geeks");
const char *name = "forGeeks";
s1 = name;
return 0;
}
Output:
Constructor called
Constructor called
The first line of output is printed by statement “String s1(“Geeks”);” and the second line
is printed by statement “s1 = name;”. The reason for the second call is, a single
parameter constructor also works as a conversion operator
#include<iostream>
int main()
{
Test t(20);
t.show();
t = 30; // conversion constructor is called here.
t.show();
getchar();
return 0;
}
The above program prints:
x = 20
x = 30
Question 2
#include<iostream>
class A
{
public:
virtual void fun() {cout << "A" << endl ;}
};
class B: public A
{
public:
virtual void fun() {cout << "B" << endl;}
};
class C: public B
{
public:
virtual void fun() {cout << "C" << endl;}
};
int main()
{
A *a = new C;
A *b = new B;
a->fun();
b->fun();
return 0;
}
Output:
C
B
A base class pointer can point to objects of children classes. A base class pointer can
also point to objects of grandchildren classes. Therefor, the line “A *a = new C;” is
valid. The line “a->fun();” prints “C” because the object pointed is of class C and fun() is
declared virtual in both A and B. The second line of output is printed by statement “b-
>fun();”.
Output of C++ Program | Set 11
Predict the output of following C++ programs.
Question 1
#include<iostream>
using namespace std;
class Point
{
private:
int x;
int y;
public:
Point(const Point&p) { x = p.x; y = p.y; }
void setX(int i) {x = i;}
void setY(int j) {y = j;}
int getX() {return x;}
int getY() {return y;}
void print() { cout << "x = " << getX() << ", y = " << getY(); }
};
int main()
{
Point p1;
p1.setX(10);
p1.setY(20);
Point p2 = p1;
p2.print();
return 0;
}
Output: Compiler Error in first line of main(), i.e., “Point p1;”
Since there is a user defined constructor, compiler doesn’t create the default
constructor. If we remove the copy constructor from class Point, the program works
fine and prints the output as “x = 10, y = 20”
Question 2
#include<iostream>
using namespace std;
int main()
{
int *ptr = new int(5);
cout << *ptr;
return 0;
}
Output: 5
The new operator can also initialize primitive data types. In the above program, the
value at address ‘ptr ‘ is initialized as 5 using the new operator.
Question 3
#include <iostream>
using namespace std;
class Fraction
{
private:
int den;
int num;
public:
void print() { cout << num << "/" << den; }
Fraction() { num = 1; den = 1; }
int &Den() { return den; }
int &Num() { return num; }
};
int main()
{
Fraction f1;
f1.Num() = 7;
f1.Den() = 9;
f1.print();
return 0;
}
Output: 7/9
The methods Num() and Den() return references to num and den respectively. Since
references are returned, the returned values can be uses as an lvalue, and the private
members den and num are modified. The program compiles and runs fine, but this
kind of class design is strongly discouraged. Returning reference to private variable
allows users of the class to change private data directly which defeats the purpose of
encapsulation.
Output of C++ Program | Set 12
Predict the output of following C++ programs.
Question 1
#include <iostream>
using namespace std;
int main()
{
cout << fun(12, ,2);
return 0;
}
Output: Compiler Error in function call fun(12, ,2)
With default arguments, we cannot skip an argument in the middle. Once an argument
is skipped, all the following arguments must be skipped. The calls fun(12) and fun(12,
2) are valid.
Question 2
#include<iostream>
using namespace std;
int main()
{
Test obj;
int x = 40;
obj.setX(x);
obj.print();
return 0;
}
Output:
x = 40
Scope resolution operator can always be used to access a class member when it is
made hidden by local variables. So the line “Test::x = x” is same as “this->x = x”
Question 3
#include<iostream>
using namespace std;
class Test
{
private:
int x;
static int count;
public:
Test(int i = 0) : x(i) {}
Test(const Test& rhs) : x(rhs.x) { ++count; }
static int getCount() { return count; }
};
int Test::count = 0;
Test fun()
{
return Test();
}
int main()
{
Test a = fun();
cout<< Test::getCount();
return 0;
}
Output: Compiler Dependent
The line “Test a = fun()” may or may not call copy constructor. So output may be 0 or
1. If copy elision happens in your compiler, the copy constructor will not be called. If
copy elision doesn’t happen, copy constructor will be called. The gcc compiler
produced the output as 0.