In short
C++ is a compiled, statically typed language created by Bjarne Stroustrup (1979-83, "C with Classes") that adds classes, function and operator overloading, references, templates, exceptions and the Standard Template Library (STL) on top of C, while keeping C's performance and low-level control. It is standardised by ISO/IEC 14882 — commonly used editions are C++11, C++14, C++17 and C++20 (C++23 is the latest edition); compile with g++ -std=c++17. In BCA/BSc-CS and MCA syllabi (IGNOU, Pune, Mumbai, Bangalore City University, AICTE model curriculum) it is the standard vehicle for teaching object-oriented programming, and it carries marks in UGC-NET and university theory and practical exams (GATE CS sets its programming questions in C, not C++). In placements it is the default language for coding rounds at TCS NQT, Infosys, Wipro, Cognizant, Zoho, Amazon and most competitive-programming based hiring, and in industry it runs trading engines, embedded firmware, CAD/graphics, databases and game engines.
Explained
From C to C++: structure, I/O and type safety
- Minimal program:
#include <iostream>→using namespace std;(orstd::cout) →int main() { ... return 0; }. Compilation stages are the same as C: preprocess → compile → assemble → link. - Stream I/O:
cout << x;(insertion),cin >> x;(extraction);<<and>>are overloaded operators, type-safe and extensible, unlikeprintf's format strings.endlinserts'\n'and flushes;'\n'alone is faster. cin >> sstops at whitespace; usegetline(cin, s)for a full line. Aftercin >> n, callcin.ignore()beforegetline.- Manipulators:
setw,setprecision,fixed(need<iomanip>);left,right,hex,boolalphalive in<ios>and are already available with<iostream>. - New/stronger types:
bool(true/false),std::string(<string>) instead of char arrays,nullptrinstead ofNULL,autotype deduction,enum class. - References:
int &r = x;is an alias — must be initialised, cannot be reseated, cannot be null. Used for pass-by-reference (void f(int &a)) and cheap read-only passing (const string &s). - Memory operators:
new/deleteandnew[]/delete[]replacemalloc/free;newcalls the constructor,deletecalls the destructor. - Namespaces:
namespace util { ... }, accessed asutil::f(), avoid name clashes;stdholds the whole standard library. - Other C++ additions:
constinstead of#definefor constants,inlinefunctions instead of macros, declaration anywhere in a block, default function arguments, function overloading,structnames usable as types withouttypedef. - Note for labs: Turbo C++ /
<iostream.h>/void main()are pre-standard and obsolete — write#include <iostream>andint main().
Functions: overloading, defaults, inline, templates of behaviour
- Function overloading — same name, different parameter list (number, type or order). Resolved at compile time (static/early binding) by exact match → promotion → standard conversion → user-defined conversion. Return type alone cannot overload.
- Default arguments:
double emi(double p, double r, int n = 12);— defaults must be the rightmost parameters, specified once (usually in the declaration). - inline: a request to substitute the body at the call site, removing call overhead; the compiler may refuse (recursion, large bodies). Member functions defined inside the class body are implicitly inline.
- Pass by value / by pointer / by reference: value copies; pointer can be reassigned and can be null; reference is the cleanest for output parameters. Return by reference is legal only for objects that outlive the call (never a local).
- const-correctness:
const int*(pointee fixed),int* const(pointer fixed),constmember function (cannot modify data members),constparameters. - Function templates:
template <class T> T maxOf(T a, T b){ return a>b?a:b; }— one definition, instantiated per type at compile time; no runtime cost. - Lambdas (C++11):
[](int a,int b){ return a<b; }, capture by value[=]or reference[&]; mainly used as comparators/predicates for STL algorithms.
Classes in C++: members, constructors, static, friend, this
- A class binds data members and member functions; access specifiers are
private(default forclass),protected,public(default forstruct). Declaration in the class, definition outside with the scope resolution operatorType::member. - Constructor: same name as the class, no return type, runs automatically on creation. Kinds: default, parameterised, copy constructor
X(const X&), and move constructorX(X&&)(C++11). - Member initialiser list:
Point(int a,int b) : x(a), y(b) {}— compulsory forconstmembers, references and base-class/member objects without a default constructor. Members initialise in declaration order. - Destructor
~X()takes no arguments, cannot be overloaded, and is called automatically at end of scope (reverse order of creation) or ondelete. Used to release memory, files, locks — this is RAII. - Shallow vs deep copy: the compiler-generated copy constructor copies pointer values, so two objects free the same block (double free). A class owning raw memory must define copy constructor, copy assignment and destructor — the Rule of Three (Rule of Five with move constructor and move assignment).
- static data member: one copy shared by all objects; declared in the class, defined once outside (
int Student::count = 0;). static member function has nothisand can use only static members; called asStudent::total(). - this pointer: implicit pointer to the invoking object; used to disambiguate names, return
*thisfor chaining, and self-comparison in assignment operators. - friend function / friend class: non-member granted access to private members (
friend void show(const X&);). Needed for symmetric operators likeoperator<<. Friendship is not inherited, not transitive, not mutual. - **Constant objects, mutable members, nested classes, object arrays, objects as parameters and return values,
explicit** single-argument constructors (block unwanted implicit conversion).
Operator overloading and type conversion
- Syntax:
returnType operator@(args). As a member function the left operand is the object (c1 + c2→c1.operator+(c2)); as a friend/global both operands are explicit — required when the left operand is not the class (2 * c,cout << c). - Unary member operators take no argument; binary member operators take one. Post-increment uses a dummy
int:X operator++(int)versus pre-incrementX& operator++(). - Cannot be overloaded:
::,.,.*,sizeof,typeid,?:, and thealignof/static_castfamily.=,(),[],->must be member functions. Precedence, associativity and arity cannot be changed, and no new symbols can be invented. - Conversions: constructor with one argument converts other-type → class; conversion operator
operator double() constconverts class → other type. - Casts:
static_cast,const_cast,dynamic_cast(safe downcast on polymorphic types, returnsnullptr/throws on failure),reinterpret_cast— preferred over C-style casts.
Inheritance and virtual functions (the C++ mechanics)
class Derived : public Base { };— modes: public (public→public, protected→protected), protected (both→protected), private (both→private, the default forclass).privatemembers of the base are never directly accessible in the derived class; useprotected.- Types: single, multiple (
: public A, public B), multilevel, hierarchical, hybrid. Base constructors run before the derived constructor; destructors run in reverse. - Diamond problem:
DinheritingBandC, both fromA, gets two copies ofA; solved by virtual base class (class B : virtual public A). - Function overriding: same signature in the derived class. With
virtualin the base, the call through a base pointer/reference dispatches to the derived version at runtime (late/dynamic binding) via the vtable and the hidden vptr in each object; withoutvirtualit is resolved statically by pointer type. Mark overrides withoverride, block further overriding withfinal. - Pure virtual function
virtual double area() const = 0;makes the class abstract — it cannot be instantiated; a derived class must implement it. This is how interfaces are expressed in C++. - Virtual destructor: mandatory in any base class deleted through a base pointer, else the derived destructor never runs (resource leak).
- Limits: constructors cannot be virtual; a virtual function called inside a constructor resolves to the current class; default arguments of virtual functions are taken statically.
- Slicing: assigning a derived object to a base object by value copies only the base part.
Templates, STL and generic programming
- Class template:
template <class T, int N> class Stack { T a[N]; ... };instantiated asStack<int,10> s;. Supports default template arguments and explicit specialisation, which must fix every parameter (template<> class Stack<char,10>); leaving one free is a partial specialisation (template<int N> class Stack<char,N>). - STL = containers + iterators + algorithms + function objects, all template-based.
| Container | Structure | Typical cost |
|---|---|---|
vector | dynamic array | index O(1), push_back amortised O(1), middle insert O(n) |
deque | segmented array | push/pop both ends O(1) |
list | doubly linked list | insert/erase O(1) at a known position, no indexing |
set / map | balanced BST (red-black) | find/insert/erase O(log n), sorted order |
unordered_set / unordered_map | hash table | average O(1), worst O(n), unordered |
stack / queue / priority_queue | adaptors | push/pop O(1); priority_queue top O(1), push/pop O(log n) |
- Iterators: input, output, forward, bidirectional (
list,map), random-access (vector,deque);begin()/end()withend()one past the last element. Modifying avectorcan invalidate iterators. - Algorithms (
<algorithm>,<numeric>):sort(O(n log n)),stable_sort,find,binary_search(needs sorted range),lower_bound,count,reverse,accumulate,max_element,for_each,transform,unique+erase. - Useful C++11+ features:
auto, range-basedfor (auto &x : v), uniform initialisationvector<int> v{1,2,3},nullptr, move semantics andstd::move, smart pointersunique_ptr/shared_ptr/weak_ptr(<memory>) sodeleteis rarely written by hand,constexpr,std::array,tuple,std::thread, structured bindings andstd::optional(C++17),std::string_view, andstd::format/ranges (C++20).
Exception handling and file streams
try { ... } catch (const Type &e) { ... } catch (...) { }withthrow expr;. The thrown object is matched to the first compatible handler; stack unwinding destroys local objects, so RAII prevents leaks.- Standard hierarchy (
<stdexcept>):exception→logic_error(invalid_argument,out_of_range) andruntime_error(overflow_error);e.what()returns the message.vector::at()throwsout_of_range;newthrowsbad_alloc. - Rethrow with a bare
throw;. Mark non-throwing functionsnoexcept. A destructor should never let an exception escape. Segmentation faults and divide-by-zero on integers are not C++ exceptions and cannot be caught portably. - **File I/O (
<fstream>):**ofstream(write),ifstream(read),fstream(both). Modes:ios::in,ios::out,ios::app,ios::trunc,ios::binary,ios::ate, combined with|. - Read loop:
while (getline(fin, line))orwhile (fin >> x)— testingfin.eof()as the loop condition processes the last record twice. - State flags
good/eof/fail/bad,clear(); positioningseekg,seekp,tellg,tellp; unformattedread/writewithreinterpret_cast<char*>for binary records;close()(the destructor closes automatically).
Key points
- C++ - a multi-paradigm (procedural + object-oriented + generic) near-superset of C - most C code compiles, but it is not strictly a superset - standardised as ISO/IEC 14882; C++11/14/17/20/23 are the editions in use.
- Reference - an alias that must be initialised and cannot be null or reseated; a pointer can be both.
- Function overloading - same name, different parameter list, resolved at compile time; return type is not part of the signature.
- Constructor - no return type, runs on creation; destructor
~X()runs on scope exit, in reverse order of construction. - Copy constructor
X(const X&)- takes its parameter by reference, because by value would recurse infinitely. - Rule of Three/Five - a class owning raw resources needs destructor + copy constructor + copy assignment (+ move pair).
- static member - one shared copy, defined once outside the class; static member functions have no
this. - friend - grants private access to a non-member; not inherited, not transitive, not symmetric.
- this - implicit pointer to the calling object; absent in static member functions.
- Operator overloading - gives operators meaning for user types;
=,(),[],->must be members;::,.,?:,sizeofcannot be overloaded. - Inheritance modes - public keeps the interface, private/protected hide it; private is the default for
class, public forstruct. - virtual function + vtable - runtime polymorphism (late binding); non-virtual calls bind statically by pointer type.
- **Pure virtual (
= 0)** - makes the class abstract; abstract classes cannot be instantiated and act as interfaces. - Virtual destructor - required in any polymorphic base class deleted via a base pointer.
- Virtual base class - removes the duplicate base copy in the diamond problem.
- Templates - compile-time genericity with no runtime overhead (contrast Java generics' type erasure).
- STL - containers, iterators, algorithms and functors;
mapis O(log n) and ordered,unordered_mapis average O(1) and unordered. - RAII and smart pointers - acquire in the constructor, release in the destructor;
unique_ptr/shared_ptrremove most manualdeletecalls.
Examples
1. Constructor/destructor order and the static counter.
#include <iostream>
using namespace std;
class Student {
static int count; // shared
int roll;
public:
Student(int r) : roll(r) { ++count; cout << "ctor " << roll << " "; }
~Student() { --count; cout << "dtor " << roll << " "; }
static int alive() { return count; }
};
int Student::count = 0; // definition outside the class
int main() {
Student a(101), b(102);
{ Student c(103); cout << "| alive=" << Student::alive() << " "; }
cout << "| alive=" << Student::alive() << endl;
}
Step by step: a then b then c are constructed → count = 3 → inner block ends, c is destroyed → count = 2 → b then a destroyed (reverse order). Output: ctor 101 ctor 102 ctor 103 | alive=3 dtor 103 | alive=2 dtor 102 dtor 101
2. Virtual function: runtime polymorphism, with numbers.
class Shape { public: virtual double area() const = 0; virtual ~Shape() {} };
class Rect : public Shape { double w,h; public:
Rect(double a,double b):w(a),h(b){} double area() const override { return w*h; } };
class Circle : public Shape { double r; public:
Circle(double x):r(x){} double area() const override { return 3.14159*r*r; } };
Shape* s[2] = { new Rect(4,2.5), new Circle(3) };
double total = 0; for (int i=0;i<2;i++) total += s[i]->area();
Rect(4, 2.5)→ 4 × 2.5 = 10.0Circle(3)→ 3.14159 × 9 = 28.27431- total = 38.27431 → prints 38.274 (with
setprecision).
If virtual were removed from area(), each call would bind to Shape::area by pointer type — with a pure virtual that is a compile error, and with a Shape::area() returning 0 the total would print 0. That contrast is the standard exam question.
3. Operator overloading on a Complex class.
class Complex {
double re, im;
public:
Complex(double r = 0, double i = 0) : re(r), im(i) {}
Complex operator+(const Complex &c) const { return Complex(re+c.re, im+c.im); }
Complex operator*(const Complex &c) const {
return Complex(re*c.re - im*c.im, re*c.im + im*c.re);
}
double abs() const { return sqrt(re*re + im*im); }
friend ostream& operator<<(ostream &o, const Complex &c) {
return o << c.re << (c.im < 0 ? "" : "+") << c.im << "i";
}
};
Complex p(3,4), q(1,2);
p + q= (3+1) + (4+2)i = 4+6ip * q= (3·1 − 4·2) + (3·2 + 4·1)i = (3 − 8) + (6 + 4)i = −5+10ip.abs()= √(9 + 16) = √25 = 5cout << pworks becauseoperator<<is a friend (left operand isostream, notComplex);2 * pwould need a globaloperator*, since the member form requires aComplexon the left.
4. STL in one program (a frequent coding-round pattern).
vector<int> v{42, 17, 93, 17, 8};
sort(v.begin(), v.end()); // 8 17 17 42 93
int sum = accumulate(v.begin(), v.end(), 0); // 177
int mx = *max_element(v.begin(), v.end()); // 93
int twos = count(v.begin(), v.end(), 17); // 2
bool has42 = binary_search(v.begin(), v.end(), 42); // true (sorted)
map<string,int> freq; // word count
for (string w : {"c++","java","c++"}) freq[w]++; // c++ -> 2, java -> 1
Check: 42 + 17 + 93 + 17 + 8 = 177. map prints in key order: c++ 2, java 1; unordered_map would print the same pairs in an unspecified order.
**5. Object layout and padding (sizeof).** On a typical 64-bit g++ build (sizes are implementation-defined):
struct A { int i; double d; char c; }; // 4 + 4 pad + 8 + 1 + 7 pad = 24
struct B { double d; int i; char c; }; // 8 + 4 + 1 + 3 pad = 16
A:intat offset 0 (4 bytes), 4 bytes padding so thedoublesits at an 8-byte boundary (8-16),charat 16, 7 bytes tail padding → 24 bytes.B:double0-8,int8-12,char12, 3 bytes tail padding → 16 bytes.- Reordering members largest-first saved 8 bytes per object — 8 MB across 1 million objects. Also note an empty class has
sizeof1, and adding a virtual function adds one vptr (8 bytes on 64-bit).
| Feature | C | C++ |
|---|---|---|
| Paradigm | Procedural | Procedural + OOP + generic |
| Data hiding | None (struct members public) | private/protected/public |
| I/O | printf/scanf (format strings) | cout/cin (type-safe streams) |
| Memory | malloc/free | new/delete, smart pointers |
| Overloading | Not allowed | Functions and operators |
| Error handling | Return codes, errno | Exceptions + return codes |
| Reuse | Functions, copy-paste | Classes, inheritance, templates, STL |
| Binding | When decided | Mechanism | Example |
|---|---|---|---|
| Static (early) | Compile time | Overload resolution, name lookup | overloaded functions, templates, non-virtual calls |
| Dynamic (late) | Run time | vptr → vtable lookup | virtual function via base pointer/reference |
Where it is used
- Finance and trading: low-latency order-matching and risk engines at NSE/BSE-connected firms and quant shops (Tower Research, Graviton, Quadeye in Bengaluru/Gurugram/Mumbai) where microseconds matter.
- Embedded, automotive and defence: firmware and control software at Bosch, Continental, Tata Elxsi, KPIT, L&T Technology Services, ISRO/DRDO labs; AUTOSAR stacks are largely C/C++.
- Systems and product engineering: databases, browsers, compilers, OS components, and the C++ cores of Indian product companies and GCCs (Amazon, Microsoft IDC, Adobe, Qualcomm, Nvidia, Samsung R&D).
- CAD, EDA, graphics and games: Autodesk/Siemens-style modellers, Unreal Engine titles at studios such as Rockstar India/Dhruva/SuperGaming; OpenCV and image-processing pipelines.
- Competitive programming and placement rounds: C++ with STL is the default for Codeforces, CodeChef, ICPC and for TCS CodeVita/NQT, Infosys HackWithInfy, Zoho and FAANG-style interviews.
- Job roles: C++ developer, systems/embedded engineer, quant developer, game programmer, SDE-1 in product firms; C++ knowledge also underpins performance work in Python extensions and Android NDK.
Interview questions
- Q: What is the difference between a pointer and a reference? A: A reference is an alias that must be initialised at declaration, cannot be null and cannot be made to refer elsewhere; a pointer is an object holding an address, can be null, reassigned and arithmetic-ed.
- Q: Why must a copy constructor take its parameter by reference? A: Passing by value would itself require a copy, calling the copy constructor again — infinite recursion;
const X&avoids the copy and allows temporaries. - Q: What is the difference between overloading and overriding? A: Overloading is several functions with the same name but different parameter lists in the same scope, resolved at compile time; overriding is a derived class redefining a base
virtualfunction with the same signature, resolved at run time. - Q: Why does a base class need a virtual destructor? A: So that
delete basePtron a derived object runs the derived destructor first; without it only the base destructor runs and the derived resources leak (undefined behaviour). - Q: How does C++ implement runtime polymorphism? A: Each polymorphic class has a vtable of function pointers; every object stores a vptr to it, and a virtual call is an indirect jump through that table — one extra indirection in cost.
- Q: Can a constructor be virtual? Can a static function be virtual? A: No to both — the object's type is not yet established during construction, and a static member function has no object and no vptr to dispatch through.
- Q: What is the diamond problem and how is it solved? A: Multiple inheritance from two classes sharing a base gives two copies of that base and ambiguous access; declaring the intermediate inheritance
virtual publickeeps a single shared copy. - Q: Difference between
structandclassin C++? A: Only the defaults —structmembers and inheritance are public by default,classprivate; otherwise both support constructors, inheritance and virtual functions. - Q: When would you choose
mapoverunordered_map? A: When sorted iteration,lower_bound-style range queries or guaranteed O(log n) worst case is needed;unordered_mapis faster on average (O(1)) but unordered and worst-case O(n). - Q: What are shallow and deep copy? A: Shallow copy duplicates pointer values so two objects share and double-free the same memory; deep copy allocates new memory and copies the contents — implemented in a user-defined copy constructor and assignment operator.
- Q: What is RAII and why does it matter with exceptions? A: Resources are acquired in a constructor and released in a destructor, so stack unwinding during an exception releases them automatically — the reason
unique_ptr,vectorandfstreamare leak-safe. - Q: What does
constmean after a member function, as indouble area() const;? A: The function promises not to modify the object's data members, so it can be called onconstobjects and throughconstreferences. - Q: Why are templates said to have zero runtime cost compared with Java generics? A: The compiler instantiates concrete code per type at compile time (no boxing, no casts), whereas Java erases the type and inserts casts at run time.
Common mistakes
- Forgetting the out-of-class definition
int Student::count = 0;for a static data member — a linker "undefined reference" error, not a compile error. - Omitting
virtual(oroverride) and then expecting a base-class pointer to call the derived function; and omitting the virtual destructor in a polymorphic base. - Mismatching
new[]/delete[]withdelete/free, or relying on the default copy constructor for a class owningnew-ed memory (double free, crash on exit). - Using
while (!fin.eof())as a read loop, which processes the last record twice; test the read itself instead. - Returning a reference or pointer to a local variable, or using an iterator after
push_backhas reallocated the vector. - Writing obsolete code in practicals —
#include <iostream.h>,void main(),conio.h/clrscr()— which does not compile with g++ on a standard-conforming setup. - Mixing
cin >>withgetlinewithoutcin.ignore(), so the firstgetlinereads the leftover newline as an empty line. - Off-by-one with
end()(it is one past the last element) and callingbinary_search/lower_boundon an unsorted range.
Related topics
C programming fundamentals · Pointers and dynamic memory · Object-oriented programming concepts · Java essentials · Data structures and algorithms · C# and .NET basics