← Back to C++ Course | Chapter 10: Polymorphism & Abstraction | Lesson 7 of 11

C++ Encapsulation

Encapsulation is keeping an object's data private and letting others use it only through safe methods, like a vending machine that hides the insides. It protects data from accidental changes.
Syntax
cpp
class ClassName {
private:
  data_type member;
public:
  data_type getMember() { return member; }
  void setMember(data_type value) { member = value; }
};

What is Encapsulation?

Encapsulation is the practice of bundling a class's data variables together with the methods that operate on them into one self-contained unit, while hiding those variables from direct modification by any code outside the class.

Example: What is Encapsulation?

cpp
// Include std::cout and std::cin
#include <iostream>

// Define the type Account
class Account {
// Members below are only accessible inside the class
private:
	double balance = 0;
// Members below can be accessed from outside the class
public:
	void deposit(double amount) { balance += amount; }
	double getBalance() { return balance; }
};

// Program execution starts in main()
int main() {
	Account acc;
	acc.deposit(100);
	// Print to the console with cout
	std::cout << acc.getBalance() << std::endl;
	// Return 0 to signal that the program finished successfully
	return 0;
}

Getters and Setters

Getters and setters are the standard public interface used to interact safely with an object's private data: getters read a value without exposing the field itself, and setters write a value in a controlled way rather than allowing direct external assignment.

Example: Getters and Setters

cpp
// Include std::cout and std::cin
#include <iostream>

// Define the type Account
class Account {
// Members below are only accessible inside the class
private:
	double balance = 0;
// Members below can be accessed from outside the class
public:
	double getBalance() { return balance; }
	void setBalance(double amount) { balance = amount; }
};

// Program execution starts in main()
int main() {
	Account acc;
	acc.setBalance(500);
	// Print to the console with cout
	std::cout << acc.getBalance() << std::endl;
	// Return 0 to signal that the program finished successfully
	return 0;
}

Data Validation

Because setters funnel every write through a single function, they give you a natural place to validate incoming data before it's actually stored, rejecting values that would leave the object in an invalid state and catching bugs closer to their source.

Example: Data Validation

cpp
// Include std::cout and std::cin
#include <iostream>

// Define the type Account
class Account {
// Members below are only accessible inside the class
private:
	double balance = 0;
// Members below can be accessed from outside the class
public:
	void setBalance(double amount) {
		if (amount >= 0) balance = amount;
	}
	double getBalance() { return balance; }
};

// Program execution starts in main()
int main() {
	Account acc;
	acc.setBalance(-50);
	// Print to the console with cout
	std::cout << acc.getBalance() << std::endl;
	// Return 0 to signal that the program finished successfully
	return 0;
}

Abstraction through Encapsulation

Encapsulation also enables abstraction: by hiding complicated internal logic behind a clean public method name, you let other code use a class's functionality without needing to understand — or depend on — how that functionality is actually implemented.

Example: Abstraction through Encapsulation

cpp
// Include std::cout and std::cin
#include <iostream>

// Define the type Account
class Account {
// Members below are only accessible inside the class
private:
	double balance = 0;
	double calculateInterest() { return balance * 0.05; }
// Members below can be accessed from outside the class
public:
	void applyInterest() { balance += calculateInterest(); }
	double getBalance() { return balance; }
};

// Program execution starts in main()
int main() {
	Account acc;
	acc.applyInterest();
	// Print to the console with cout
	std::cout << acc.getBalance() << std::endl;
	// Return 0 to signal that the program finished successfully
	return 0;
}

Benefits of Encapsulation

The practical payoff of encapsulation is that it keeps code secure, modular, and easy to maintain: because outside code only ever touches the public interface, you're free to rewrite a class's internal implementation later without breaking anything that already uses it.

Example: Benefits of Encapsulation

cpp
// Include std::cout and std::cin
#include <iostream>

// Define the type Account
class Account {
// Members below are only accessible inside the class
private:
	double balance = 100;
// Members below can be accessed from outside the class
public:
	double getBalance() { return balance; }
};

// Program execution starts in main()
int main() {
	Account acc;
	// Print to the console with cout
	std::cout << acc.getBalance() << std::endl;
	// Return 0 to signal that the program finished successfully
	return 0;
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Making data members public, which bypasses the checks that encapsulation should provide.
  2. Writing a setter that accepts invalid values without validating them.
  3. Returning a non-const reference to a private member, which lets outside code modify it directly.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.