Language Selector

8.3 — Public vs private access specifiers

Public and private members

Consider the following struct:

In this program, we declare a DateStruct and then we directly access its members in order to initialize them. This works because all members of a struct are public members by default. Public members are members of a struct or class that can be accessed from outside of the struct or class. In this case, function main() is outside of the struct, but it can directly access members month, day, and year, because they are public.

On the other hand, consider the following almost-identical class:

If you were to compile this program, you would receive errors. This is because by default, all members of a class are private. Private members are members of a class that can only be accessed by other members of the class. Because main() is not a member of DateClass, it does not have access to date’s private members.

Access specifiers

Although class members are private by default, we can make them public by using the public keyword:

Because DateClass’s members are now public, they can be accessed directly by main().

The public keyword, along with the following colon, is called an access specifier. Access specifiers determine who has access to the members that follow the specifier. Each of the members “acquires” the access level of the previous access specifier (or, if none is provided, the default access specifier).

C++ provides 3 different access specifier keywords: public, private, and protected. Public and private are used to make the members that follow them public members or private members respectively. The third access specifier, protected, works much like private does. We will discuss the difference between the private and protected access specifier when we cover inheritance.

Mixing access specifiers

Classes can (and almost always do) use multiple access specifiers to set the access levels of each of its members.

In general, member variables are usually made private, and member functions are usually made public. We’ll take a closer look at why in the next lesson.

Rule: Make member variables private, and member functions public, unless you have a good reason not to.

Let’s take a look at an example of a class that uses both private and public access:

This program prints:


Note that although we can’t access date’s members variables m_month, m_day, and m_year directly from main (because they are private), we are able to access them indirectly through public member functions setDate() and print()!

The group of public members of a class are often referred to as a public interface. Because only public members can be accessed from outside of the class, the public interface defines how programs using the class will interface with the class. Note that main() is restricted to setting the date and printing the date. The class protects the member variables from being accessed or edited directly.

Some programmers prefer to list private members first, because the public members typically use the private ones, so it makes sense to define the private ones first. However, a good counterargument is that users of the class don’t care about the private members, so the public ones should come first. Either way is fine.

Structs vs classes revisited

Now that we’ve talked about access specifiers, we can talk about the actual differences between a class and a struct in C++. A class defaults its members to private. A struct defaults its members to public. That’s it!

Quiz time

1a) What is a public member?

Show Solution

1b) What is a private member?

Show Solution

1c) What is an access specifier?

Show Solution

1d) How many access specifiers are there, and what are they?

Show Solution

2) Write a simple class named Point3d. The class should contain:
* Three private member variables of type double named m_x, m_y, and m_z;
* A public member function named setValues() that allows you to set values for m_x, m_y, and m_z.
* A public member function named print() that prints the Point in the following format: <m_x, m_y, m_z>

Make sure the following program executes correctly:

This should print:

<1, 2, 3>

Show Solution

3) Now let’s try something a little more complex. Let’s write a class that implements a simple stack. Review lesson 7.9 -- The stack and the heap if you need a refresher on a what a stack is.

The class should be named Stack, and should contain:
* A private fixed array of integers of length 10.
* A private integer to keep track of the length of the stack.
* A public member function named reset() that sets the length to 0 and all of the element values to 0.
* A public member function named push() that pushes a value on the stack. push() should return false if the array is already full, and true otherwise.
* A public member function named pop() that pops a value off the stack and returns it. If there are no values on the stack, it should return -1.
* A public member function named print() that prints all the values in the stack.

Make sure the following program executes correctly:

This should print:

( )
( 5 3 8 )
( 5 3 )
( )

Show Solution

8.4 -- Access functions and encapsulation
8.2 -- Classes and class members

29 comments to 8.3 — Public vs private access specifiers

  • vinoth

    by default class is public or private in c++

  • Spock

    Another great tutorial. You write really well man.

  • Joseph

    Does C++ only accept class members declared with the public:, private: and protected: access specifiers?
    Would writing them like this also work?

    • C++ newbie

      I just tried compiling that and it didn’t work.  It said that it needed the colon after public.  I know you can declare things like this in other languages, though (like Java)

  • Marvin

    I’m missing the quizzes to apply my just received knowledge like in former chapters!

  • Nate

    I did not struggle with c++ at all until I hit classes.  I have been stuck on them for a week now and feel that I am making very little progress.  Is that normal for most people?  Thankyou

    • Alex

      Yes, making the shift from normal functions to objects can be a little hard to wrap your brain around. But once you “get it”, you won’t want to go back.

      What specifically are you stuck on?

  • I have few questions Alex…

    In the previous lesson you said that structs can’t include functions. In this lesson I have a confusion with this line:

    "One of the primary differences between classes and structs is that classes can explicitly use access specifiers to restrict who can access members of a class"

    The following program works fine:

    I can define a function inside a struct. I can strict members using public and private. Till this point, I only can see a single difference between struct and classes that class members are by default private and struct members are public. Are we missing something???

    The wikipedia also has an article containing an example where struct is used and shown that its members are restricted.

    • Alex

      Yes, the previous statement was misleading (and has been corrected) -- the intent was to say that data-only structs were non-object-oriented, not all structs. In C++, structs are like classes where all the members are public by default.

  • Colleen

    I’m very glad you include sample code.

    What IDE are you using to compile and run your code? I have NetBeans installed on my computer, and I tried to run the “employee” example program, but I got compilation errors (“‘cout’ is not a member of ‘std'”). Do you recommend NetBeans-or do you have an IDE you’d recommend?


    • Alex

      NetBeans is okay, but it sounds like your compiler is out of date. NetBeans has support for multiple compilers -- maybe you can change to a more modern compiler version.

  • Batyr

    Hey, Alex! Could you please explain me why if m_length is equal to 10 return false? why not 9?

    for example, if length is already 9, it will continue to the next statement, and how it is going to assign [m_length++] => [10] to the array? if subscripts are from 0 to 9? Or maybe bcz of increment operator order?


    • Alex

      We used the postfix increment operator here, not the prefix increment operator. So m_length isn’t incremented until after it’s evaluated.

      So when m_length is 9 and the function is called:

      is essentially the same as:

      You can see that m_length is evaluated to be 9 first, then it’s incremented to 10.

      And if m_length is 10, that’s an invalid index for our array, so we ignore the push request so we don’t walk off the end of the array.

  • BlueTooth4269

    Isn’t static technically an access specifier if you’re defining your class in another cpp file?

  • sitaram chhimpa

    Can anyone suggest while below code is not working for 3rd question …it is giving me initial len as -2 while initilized by 0 in reset function.

    • Alex

      you’re not initializing your member variable len, you’re initializing a new local variable with the same name instead.

      Remove the int prefix so it knows you mean member variable len instead of a new local variable.

  • John Mounir

    this is extremely helpful tutorial, Thank you so much.

  • P

    shouldn’t it be

    if we want to return the popped valued?

    • Alex

      No. As implemented, length holds the index of the next free element (which is one element past the top of the stack). Therefore, we need to first decrement (to get to a valid element) and then evaluate.

  • Shiva

    Hi Alex, I have a couple of questions:

    * Use of private: in class declarations given in the quiz solutions is superfluous. Is it just for demonstration or is that a programming practice?
    * This might sound a bit dumb: is it preferable not to prefix public member functions with m_ ?

    In Quiz #3, you didn’t specify what pop() should return if there are values on the stack.

    BTW nice lesson, I liked the quiz questions very much. Brilliant! :)

    • Shiva

      Sorry, I meant to ask: is it preferable not to prefix public members with m_ ? If it is only for private members, then what about private member functions (if any)?

      • Alex

        By common convention:
        All public and private member variables should be prefixed by m_ (unless they are static, in which case they should use s_).
        All public and private member functions should not use a prefix.

    • Alex

      1) Yes, explicitly declaring private can be superfluous. However, I always add it, both because it makes my intent explicit, and that way, if I later decide to add something public above it, I don’t risk accidentally making all of the members that were implicitly private now public. Since there’s no performance penalty for doing so, I like being a little defensive here.
      2) Usually only member variables are prefixed with m_. Member functions typically aren’t, regardless of whether they’re public or private.
      3) I’ve updated the instructions to be explicit about what pop() should return. Thanks for pointing that out.

  • T

    Aha!! I did it all with std::array only to find out that it would not work!

  • Jim

    In this exercise.

    Moot point, why make a class Point3d private, when your using all three of its members variables as input in the two public functions.

Leave a Comment

Put C++ code inside [code][/code] tags to use the syntax highlighter




2 × four =