Access Control in C++ Classes
A class declaration defines a new class type and lists its members: member functions and data members.
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?
Reveal 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.
- class Counter: the keyword class followed by the class name
- public: an access specifier that opens the public section
- void
increment(); and intvalue();: 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
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.
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.
| Feature | Member function | Data member |
|---|---|---|
| Role in the class | Accesses and manipulates data members; performs operations | Stores data within a class object |
| How it is recognized | Declared with a parameter list | Plain variable declaration with no parameter list |
| Example from Counter | void increment(); | int count; |
| Typical access in a well-designed class | Public, forming the interface outside code uses | Private, 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
- 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
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?
- 1Find the access label for each member
increment()andvalue()sit under public:. count sits under private:. - 2Check the public calls
Public members are accessible from anywhere, so
c.increment()andc.value()are allowed frommain(). - 3Check 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. - 4Compare the outcome
Outside code reaches the class only through its public members. The private data stays protected.
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.
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 likeclass Counter { int count; public: void increment(); };Why it failsThe access specifier applies to members after it. Here count appears before any label, so it is not under public:.
Do this insteadPlace 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 failsAn access specifier applies to every member after it until the next specifier appears.
Do this insteadRead 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 likeint size; is a data member, while int size(); is a member function.Why it failsThe 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 insteadLook 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
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.