Access Specifiers
public, protected, and private control which code may name a member, enforcing the boundary between a class’s interface and its implementation.
How it works
Access is a compile-time check on who is naming the member, not a runtime guard — there is no memory protection, and a cast or offset can still reach the bytes.
| Specifier | Accessible from |
|---|---|
public | anywhere |
protected | the class and its derived classes |
private | the class and its friend-functions-classes only |
- Access is per-class, not per-object: a member function of
Widgetcan touch theprivatemembers of anyWidget, including a different instance passed as an argument. - Specifiers apply from their label until the next label;
structstartspublic,classstartsprivate(structs). - Inheritance has its own access mode (
class D : private B) that caps how inherited members are exposed — see inheritance. protectedis the most misused: it breaks encapsulation toward subclasses, coupling them to your layout.
Why it matters
Access control is the mechanism behind encapsulation: by hiding representation, you keep the freedom to change it without breaking callers. It is also what makes class invariants enforceable — if a field is private, the only way to change it is through methods you wrote to keep state valid.
Example
class Account {
long cents_ = 0; // private: invariant-protected
protected:
void audit(); // visible to subclasses
public:
void deposit(long c) { cents_ += c; }
bool merge(const Account& o) { // per-class access:
cents_ += o.cents_; // reaches o's PRIVATE field — OK
return true;
}
};merge reading o.cents_ compiles because access is keyed on the class, not the object.
Pitfalls
- Access is not security:
reinterpret_castor a#define private publichack defeats it; never rely on it to hide secrets. privatedoes not hide a member from name lookup or overload resolution — a private overload can still be selected, then rejected with an access error.- Overusing
protecteddata turns subclasses into a fragile API surface; preferprivatedata +protectedmethods. - Changing a member’s access can silently change which overload wins in derived code.