← Back to C++ Course | Chapter 9: Inheritance | Lesson 2 of 8

C++ Inheritance Access Control

The access specifier used when inheriting (public, protected, or private) controls how the base class's public and protected members appear in the derived class, changing what further-derived classes and outside code can see.

public Inheritance

With public inheritance, the base class's public members stay public and its protected members stay protected in the derived class, which is the most common and intuitive form of inheritance.

Example: public Inheritance

cpp
#include <iostream>

class Base {
public:
	int a = 1;
protected:
	int b = 2;
};

class Derived : public Base {
public:
	void show() { std::cout << a << " " << b << std::endl; }
};

int main() {
	Derived d;
	std::cout << d.a << std::endl;
	d.show();
	return 0;
}

protected Inheritance

With protected inheritance, both the base class's public and protected members become protected in the derived class, hidden from code outside the class hierarchy but still usable by further subclasses.

Example: protected Inheritance

cpp
#include <iostream>

class Base {
public:
	int a = 1;
};

class Derived : protected Base {
public:
	void show() { std::cout << a << std::endl; }
};

int main() {
	Derived d;
	// d.a would fail to compile: no longer public
	d.show();
	return 0;
}

private Inheritance

With private inheritance, both the base class's public and protected members become private in the derived class, meaning even further subclasses can no longer access them directly.

Example: private Inheritance

cpp
#include <iostream>

class Base {
public:
	int a = 1;
};

class Derived : private Base {
public:
	void show() { std::cout << a << std::endl; }
};

int main() {
	Derived d;
	// d.a would fail to compile: private inheritance hides it entirely
	d.show();
	return 0;
}

Access Specifier Summary Table

The three inheritance access specifiers each transform the base class's public and protected members differently in the derived class, while private base members are never accessible in the derived class no matter which specifier is used.

Example: Access Specifier Summary Table

cpp
#include <iostream>

class Base {
public:
	int pub = 1;
protected:
	int prot = 2;
private:
	int priv = 3;
};

class PublicDerived : public Base {};
class ProtectedDerived : protected Base {};
class PrivateDerived : private Base {};

int main() {
	PublicDerived d;
	std::cout << d.pub << std::endl;
	return 0;
}

Choosing the Right Inheritance Access

public inheritance is used for a true is-a relationship where the derived class should expose the base's interface, while protected and especially private inheritance are used less often, mainly to model implementation reuse without exposing it publicly.

Example: Choosing the Right Inheritance Access

cpp
#include <iostream>

class Animal {
public:
	void eat() { std::cout << "Eating" << std::endl; }
};

class Dog : public Animal {
	// public inheritance: a Dog genuinely "is-a" Animal
};

int main() {
	Dog d;
	d.eat();
	return 0;
}

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.