Concepts / Access Control in C++ Classes

Access Control in C++ Classes

A class declaration defines a new class type and lists its members: member functions and data members.

  • Programming

Why Programs Group Data With Operations

Programs often need to represent a thing that has both data and operations on that data. A bank account has a balance and operations that change it. A list of numbers has values and operations that read or extend them. C++ lets you bundle both into one unit called a class. A class declaration is the C++ statement that defines a new class type, giving that type a name and listing what belongs to it. Once a class type is defined, you can work with values of that type in the same way you work with built-in types such as int and double.

What do you think happens?

Suppose a class Counter has a public member function increment() and a private data member count. Can code in main() call increment() on a Counter object?

  • Yes, because increment() is public

  • No, because every member of a class is hidden from outside code

Reveal answer
Answer:

Yes, because increment() is public

Public members are accessible from anywhere, so outside code can call increment(). The private data member count, by contrast, is accessible only within the class. The rest of this article explains why that split exists and how to read it from a declaration.

Anatomy of a Class Declaration

A class declaration begins with the keyword class, followed by the name of the class. The body is enclosed in braces, and the declaration ends with a closing brace and a semicolon. Inside the body, the words public and private each followed by a colon divide the members into labeled sections. Every member declaration inside the body ends with its own semicolon. A class contains members, and members come in two kinds: member functions and data members.

cpp
Notes on the code
  • class Counter: the keyword class followed by the class name
  • public: an access specifier that opens the public section
  • void increment(); and int value();: member functions, each with a parameter list and a semicolon
  • private: an access specifier that opens the private section
  • int count;: a data member, a plain variable declaration with no parameter list
  • }; : the closing brace and semicolon that end the declaration
classkeyword that starts a classtypeCounterthe class namepublic:access specifier for themembers that followvoid increment();member functionint value();member functionprivate:access specifier for themembers that followint count;data membernames the typebody openssections divide the body
Where each part of the Counter declaration sits, and what each label or section contains.

Access Specifiers as Section Labels

The access specifiers public and private control who can use the members that follow them. Public members are accessible from anywhere, and private members are accessible only within the class. This is the entire rule the access specifiers enforce: a label decides the visibility of the members beneath it.

An access specifier applies to every member after it, until the next specifier appears. You do not need to repeat the label on each line. In the Counter example, the public: label covers increment() and value(), and the private: label covers count. The access specifier is a property of the section, not of an individual declaration. If a later member appeared after another public: label, it would again be public, because the new label starts a new section.

Outside codeCounter classpublic sectionincrement()countvalue()private sectioncontainscontainscontainscontainscontainscan callblocked
Which members outside code can touch directly, and which are hidden behind the class boundary.

Member Functions Versus Data Members

Member functions and data members are both declared inside the class body, but they play different roles. A member function is a function that is part of the class. Its job is to access and manipulate data members, and it can perform operations on class objects. A data member is a variable that is part of the class. Its job is to store data within a class object.

FeatureMember functionData member
Role in the classAccesses and manipulates data members; performs operationsStores data within a class object
How it is recognizedDeclared with a parameter listPlain variable declaration with no parameter list
Example from Countervoid increment();int count;
Typical access in a well-designed classPublic, forming the interface outside code usesPrivate, hidden behind the member functions

Comparing the two kinds of class members

The source notes that data members can be accessed and manipulated using member functions. This is the pattern that access control makes possible. Outside code does not reach into the stored values directly; it calls member functions, and those functions read or change the data on its behalf. The public member functions form the interface, and the private data members hold the stored values.

Tracing Access in a Small Program

cpp
Notes on the code
  • Counter c; creates an object of the class type
  • c.increment(); calls a public member function, which is allowed
  • int n = c.value(); calls another public member function and stores its result
  • c.count = 5; tries to touch the private data member directly, which is not allowed from outside the class
Worked example

Deciding which lines outside the class are allowed

Given the Counter declaration, which of the three outside statements in main() are allowed: c.increment(), c.value(), and c.count = 5?

  1. 1
    Find the access label for each member

    increment() and value() sit under public:. count sits under private:.

  2. 2
    Check the public calls

    Public members are accessible from anywhere, so c.increment() and c.value() are allowed from main().

  3. 3
    Check the private access

    count is private, so it is accessible only within the class. The statement c.count = 5 is made from outside the class and is therefore not allowed.

  4. 4
    Compare the outcome

    Outside code reaches the class only through its public members. The private data stays protected.

Result

c.increment() and c.value() are allowed; c.count = 5 is not allowed because count is private.

Predicting Accessibility From a Declaration

The source gives a procedure that works on any class declaration. Find the access labels first, then sort each member by whether it is followed by a parameter list. Declarations with a parameter list are member functions. Plain variable declarations are data members. Once each member has an access group, the accessibility question becomes a simple check, as shown in the flowchart below.

Find the memberNearest access labelabove itIs the label public:?Usable from outsidecodeAccessible onlyinside the classlook upwardread labelyesno, private
The step-by-step reasoning that determines whether outside code can use a given member.

The Vector Class as a Source Example

The source uses a single running example: a class named Vector. Vector is a small container that holds a sequence of double values. Its declaration shows every part a class declaration usually contains. Three member functions sit under public: a Vector function, operator[], and size. These public functions form the interface. Two data members sit under private: elem and sz. The source comments on elem: it points to an array of sz doubles. elem records where the stored doubles live, and sz records how many there are. Neither member alone describes the whole collection, so together they describe a sequence of values.

Applying the procedure from the previous section to Vector gives the same answer each time. The public functions Vector, operator[], and size can be used from outside code. The private data members elem and sz cannot be read or changed directly from outside code; the public functions are the route through which outside code reaches the data the class holds.

Mistakes Beginners Make With Access Labels

  • Common mistake

    Assuming a member is public because it appears near the top of the class

    What it looks like
    class Counter { int count; public: void increment(); };
    Why it fails

    The access specifier applies to members after it. Here count appears before any label, so it is not under public:.

    Do this instead

    Place the public: label before the members that outside code should use, and check which label is nearest above each member.

  • Common mistake

    Thinking a label must be repeated on every line

    Why it fails

    An access specifier applies to every member after it until the next specifier appears.

    Do this instead

    Read each label as opening a section. One public: label covers all members beneath it until the next label.

  • Common mistake

    Treating a data member as a function because it is named like an action

    What it looks like
    int size; is a data member, while int size(); is a member function.
    Why it fails

    The presence of a parameter list, even an empty one, is what marks a member function. A plain variable declaration is a data member.

    Do this instead

    Look for the parentheses. Declarations with a parameter list are member functions; plain variable declarations are data members.

  • Common mistake

    Making data members public by default, which lets outside code change stored values directly instead of going through member functions

Practice Reading a Declaration

EASY

Consider this declaration: class Account { public: void deposit(); int balance(); private: int total; }; Which members can code outside the class use directly? Which member stores data, and which members perform operations on it? Explain your answer using the access labels.

Hints
  • Find the public: label first and list the members that sit beneath it.
  • Look for parentheses: members with a parameter list are member functions, and plain variables are data members.
  • Remember that private members are accessible only within the class.

Key Takeaways

  • A class declaration defines a new class type and lists its members, which are member functions and data members.
  • The access specifiers public and private control who can use the members that follow them: public members are accessible from anywhere, and private members only within the class.
  • An access specifier applies to every member after it until the next specifier, so it is a property of the section rather than of each line.
  • Member functions access and manipulate data members, while data members store data within a class object; public member functions typically form the interface and private data members hold the stored values.

Related concepts

More concepts starting with A