C++ Access Specifiers

Welcome to The Coding College! In this tutorial, we’ll explore Access Specifiers in C++. Access specifiers are an essential part of encapsulation, which is one of the fundamental principles of Object-Oriented Programming (OOP). They determine the level of access that different parts of a program have to the members (variables and functions) of a class.

What Are Access Specifiers?

Access specifiers in C++ control the visibility and accessibility of class members. There are three main access specifiers:

  1. public
  2. private
  3. protected

Syntax:

class ClassName {
    public:
        // Public members
    private:
        // Private members
    protected:
        // Protected members
};

1. Public Access

Members declared as public are accessible from anywhere in the program.

Example:

#include <iostream>
using namespace std;

class Car {
public:
    string brand;
    int year;

    void displayInfo() {
        cout << "Brand: " << brand << ", Year: " << year << endl;
    }
};

int main() {
    Car car1;
    car1.brand = "Toyota";
    car1.year = 2021;

    car1.displayInfo();  // Accessible outside the class
    return 0;
}

Output:

Brand: Toyota, Year: 2021

2. Private Access

Members declared as private can only be accessed within the same class. They cannot be accessed directly from outside the class.

Example:

#include <iostream>
using namespace std;

class Car {
private:
    string brand;

public:
    void setBrand(string b) {
        brand = b;  // Accessible inside the class
    }

    void displayBrand() {
        cout << "Brand: " << brand << endl;
    }
};

int main() {
    Car car1;
    car1.setBrand("Honda");  // Access through a public method
    car1.displayBrand();

    // car1.brand = "Toyota";  // Error: brand is private
    return 0;
}

Output:

Brand: Honda  

3. Protected Access

Members declared as protected are accessible within the class itself and by derived (child) classes. They are not accessible from outside the class.

Example:

#include <iostream>
using namespace std;

class Vehicle {
protected:
    string brand;

public:
    void setBrand(string b) {
        brand = b;
    }
};

class Car : public Vehicle {
public:
    void displayBrand() {
        cout << "Brand: " << brand << endl;  // Accessible in derived class
    }
};

int main() {
    Car car1;
    car1.setBrand("Ford");
    car1.displayBrand();

    // car1.brand = "Toyota";  // Error: brand is protected
    return 0;
}

Output:

Brand: Ford  

Access Specifiers Summary

SpecifierAccess from Same ClassAccess from Derived ClassAccess from Outside Class
publicYesYesYes
privateYesNoNo
protectedYesYesNo

Why Use Access Specifiers?

  1. Encapsulation: Helps hide sensitive data and ensures better control over how data is accessed and modified.
  2. Security: Protects data from unintended access or modification.
  3. Inheritance Control: Provides flexibility in controlling access to data in derived classes.

Real-Life Example: Bank Account

#include <iostream>
using namespace std;

class BankAccount {
private:
    double balance;  // Private: cannot be accessed directly

public:
    BankAccount(double initialBalance) {
        balance = initialBalance;
    }

    void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
            cout << "Deposited: $" << amount << endl;
        } else {
            cout << "Invalid deposit amount!" << endl;
        }
    }

    void withdraw(double amount) {
        if (amount > 0 && amount <= balance) {
            balance -= amount;
            cout << "Withdrawn: $" << amount << endl;
        } else {
            cout << "Invalid withdrawal amount!" << endl;
        }
    }

    void displayBalance() {
        cout << "Current Balance: $" << balance << endl;
    }
};

int main() {
    BankAccount account(500.0);

    account.deposit(150.0);       // Public method
    account.withdraw(100.0);      // Public method
    account.displayBalance();     // Public method

    // account.balance = 1000.0;  // Error: balance is private
    return 0;
}

Output:

Deposited: $150  
Withdrawn: $100  
Current Balance: $550  

Public, Private, and Protected in Inheritance

Access specifiers also play a crucial role in inheritance.

Example:

#include <iostream>
using namespace std;

class Base {
public:
    int publicVar = 1;

private:
    int privateVar = 2;

protected:
    int protectedVar = 3;
};

class Derived : public Base {
public:
    void display() {
        cout << "Public: " << publicVar << endl;       // Accessible
        // cout << "Private: " << privateVar << endl;  // Not Accessible
        cout << "Protected: " << protectedVar << endl; // Accessible
    }
};

int main() {
    Derived obj;
    obj.display();
    cout << "Public: " << obj.publicVar << endl;   // Accessible
    // cout << "Protected: " << obj.protectedVar << endl;  // Not Accessible
    return 0;
}

Output:

Public: 1  
Protected: 3  
Public: 1  

Access Specifiers in Practice

Encapsulation for a Student Management System

#include <iostream>
using namespace std;

class Student {
private:
    string name;
    int age;

public:
    void setDetails(string n, int a) {
        name = n;
        age = a;
    }

    void displayDetails() {
        cout << "Name: " << name << ", Age: " << age << endl;
    }
};

int main() {
    Student student1;
    student1.setDetails("Alice", 21);
    student1.displayDetails();

    // student1.name = "Bob";  // Error: name is private
    return 0;
}

Output:

Name: Alice, Age: 21  

Key Points to Remember

  1. public: Open to all.
  2. private: Accessible only within the class.
  3. protected: Shared between a class and its derived classes.
  4. Encapsulation relies heavily on private and protected members.

Explore More at The Coding College

Discover more tutorials, guides, and coding tips on The Coding College.

Leave a Comment