C++ Programming Tutorial
Learn modern C++ step-by-step — from basics to advanced features like templates, STL, and smart pointers. Clear explanations with practical, runnable examples.
C++ Classes and Objects
A class is a user-defined type that bundles data (member variables) and behavior (member functions) together. Objects are instances of a class. Classes are the foundation of object-oriented programming in C++.
Defining a Class
#include <iostream>
#include <string>
class Dog {
private: // only accessible inside the class
std::string name;
int age;
public: // accessible from outside
// Constructor — initializes the object
Dog(std::string n, int a) : name(std::move(n)), age(a) {}
// Member functions (methods)
void bark() const {
std::cout << name << " says Woof!
";
}
std::string get_name() const { return name; }
int get_age() const { return age; }
void set_age(int new_age) {
if (new_age >= 0) age = new_age;
}
};
int main() {
Dog rex("Rex", 3);
rex.bark(); // Rex says Woof!
std::cout << rex.get_name() << " is " << rex.get_age() << " years old
";
rex.set_age(4);
// rex.name = "X"; // ERROR: name is private
return 0;
}Constructors and Destructors
#include <iostream>
#include <string>
class Connection {
std::string host;
int port;
bool connected;
public:
// Default constructor
Connection() : host("localhost"), port(8080), connected(false) {
std::cout << "Default connection created
";
}
// Parameterized constructor
Connection(std::string h, int p)
: host(std::move(h)), port(p), connected(false) {
std::cout << "Connection to " << host << ":" << port << "
";
}
// Destructor — called when object goes out of scope
~Connection() {
if (connected) disconnect();
std::cout << "Connection destroyed
";
}
void connect() { connected = true; }
void disconnect() { connected = false; }
};
int main() {
Connection c1; // calls default constructor
Connection c2("api.example.com", 443); // calls parameterized
c2.connect();
return 0;
} // destructors called automatically hereAccess Specifiers
| Specifier | Inside class | Derived class | Outside | Use case |
|---|---|---|---|---|
private | Yes | No | No | Internal state (default for class) |
protected | Yes | Yes | No | State accessible to subclasses |
public | Yes | Yes | Yes | Public API (methods, constructors) |
Operator Overloading
#include <iostream>
class Vector2D {
public:
double x, y;
Vector2D(double x, double y) : x(x), y(y) {}
// Overload + operator
Vector2D operator+(const Vector2D& other) const {
return {x + other.x, y + other.y};
}
// Overload == operator
bool operator==(const Vector2D& other) const {
return x == other.x && y == other.y;
}
// Overload << for printing
friend std::ostream& operator<<(std::ostream& os, const Vector2D& v) {
return os << "(" << v.x << ", " << v.y << ")";
}
};
int main() {
Vector2D a(1, 2), b(3, 4);
Vector2D c = a + b;
std::cout << c << "
"; // (4, 6)
std::cout << std::boolalpha << (a == b) << "
"; // false
return 0;
}The Rule of Five
If your class manages a resource (heap memory, file handle, socket), you should define or delete these five special members:
- Destructor — releases the resource
- Copy constructor — deep-copies the resource
- Copy assignment operator — cleans up old, copies new
- Move constructor — transfers ownership (C++11)
- Move assignment operator — cleans up old, transfers new (C++11)
For most classes, prefer using RAII wrappers (std::unique_ptr, std::string, std::vector) so the compiler-generated defaults work correctly.
Best Practices
- Keep data
privateand expose it through public methods (encapsulation). - Use the member initializer list in constructors for efficiency.
- Mark methods
constwhen they do not modify the object state. - Prefer
= defaultand= deletefor special members over empty implementations. - Use
structfor simple data aggregates;classfor types with invariants.
Keep Practicing
Use the online compiler to run every example and experiment with modifications. The best way to learn C++ is by writing code — even small programs build strong foundations.