Language Selector

8.4 — Access functions and encapsulation

Access functions

An access function is a short public function whose job is to retrieve or change the value of a private member variable. For example, in a String class, you might see something like this:

GetLength() is an access function that simply returns the value of m_nLength.

Access functions typically come in two flavors: getters and setters. Getters are functions that simply return the value of a private member variable. Setters are functions that simply set the value of a private member variable.

Here’s an example class that has some getters and setters:

Why bother to make a member variable private if we’re going to provide public access functions to it? The answer is: “encapsulation”.


In real life, it is common to use something without knowing how it actually works. For example, your TV remote provides buttons that allow you to do things like turn your TV on and off and adjust the volume. However, the details of how the remote is actually implemented is hidden away. This is useful because it allows you to use the remote without having to worry about the details of why it works or how it was implemented. If gnomes broke into your house in the middle of the night and replaced the internals of your TV remote with a new (but compatible) technology, you’d probably never even notice.

Encapsulation is the idea of hiding the details of how something is implemented and instead exposing an interface to the user. This allows the user to use the item without having to worry about how it is implemented.

In C++, access specifiers allow us to implement encapsulation within our classes. This is typically done by making ALL member variables of a class private, and providing public functions (often access functions) that allow the user to work with the class. Although this may seem more burdensome than providing public access directly, doing so actually provides several very useful benefits that help encourage class reusability and maintainability.

Perhaps most importantly, sometimes it turns out that the initial implementation of a class is too slow or uses too much memory, and a more complex solution is needed. Encapsulating the implementation means that the implementation of a class can be completely changed, and so long as the interface remains the same, the users of the class do not have to worry about the changes at all!

Consider this simple example:

While this program works fine, what would happen if we decided to rename m_nValue? We’d also break our program! Encapsulation gives us the ability to change our classes without breaking all the code that uses them.

Here is the encapsulated version of this class that uses access functions to access m_nValue:

Now when we decide to rename m_nValue, we only need to change SetValue and GetValue() to reflect the change. Our program does not need to be changed at all!

Second, hiding the details about how a class is implemented means a programmer can use the class without knowing how it was implemented. This lowers the time needed to learn how to use a class, and makes the class much easier to work with.

Third, encapsulation helps prevent accidental changes and misuse. Because the member variables can not be accessed directly, this helps prevent inadvertent changing of values. Furthermore, it is often the case that when a value is modified, other values also need to be updated. For example, in a typical String class, when the string is modified, the length also needs to be updated. If the user has direct access to the string, he/she may forget to update the length when the string is changed. However, an interface function that allows the user to change the string can automatically update the length whenever the string is changed, meaning the user doesn’t even have to worry about it!

And finally, encapsulation helps you debug the program when something goes wrong. Often when a program does not work correctly, it is because one of our member variables has an incorrect value. If everyone is able to access the variable directly, tracking down which piece of code modified the variable can be difficult. However, if everybody has to call the same function to modify a variable, you can simply breakpoint that function and watch as each caller changes the value until you see where it goes wrong.

As you can see, encapsulation provides a lot of benefits for just a little bit of effort. In particular, the ability to change the implementation details of the class without affecting any of the programs that use the class is paramount to code maintainability!

8.5 -- Constructors
8.3 -- Public vs private access specifiers

37 comments to 8.4 — Access functions and encapsulation

  • Jeffey

    on your last 2 examples there is an error.

    std::cout << cChange.GetValue() << endl;

    needs to be changed to:

    std::cout << cChange.GetValue() << std::endl;

    though im sure most can figure it out this late in the tutorial.

    [ Fixed. Thanks! -Alex ]

    • Tom

      When I try the “fixed example”

      I get the errors:

      g++ j39.cpp -g -o xxx
      j39.cpp: In function ‘int main()’:
      j39.cpp:15: error: ‘cout’ is not a member of ‘std’
      j39.cpp:15: error: ‘endl’ is not a member of ‘std’

  • five


    So if I’m understanding your venacular right, encapsulation is an upgrade thru conversion…I need to understand this stuff before I graduate to the next section…

    GeeeZZZZZuuuSSSSS! :)


    Alex is it bad if I don’t declare the getters and setters by grouping them in two groups as u did above??
    For example I wrote this program:

    • Quinn

      It’s not necessarily “bad”, per se, but there are several conditions where you wouldn’t want to make a getter and setter method for each class variable. Like Alex had mentioned before, a length variable for a String class should probably only have a getter interface, not a setter. So in the class you mentioned above, those are all probably perfectly reasonable interface methods (except perhaps SetId, which should, if set by the user at all, be set during instantiation by the constructor, covered in the next lesson). Also, you should have a convenience function that sets everything. I would build it like this:

  • Them damn gnomes!! They get everywhere!

    • Pintsize

      I also laughed about the gnome thing… 😛

      Anyway… Great explanation. It really shows the benefits of working with encapsulation. The Debugging argument is great.

  • Ngugi Thomas

    You are my best teachers

  • Marko

    Alex just want to say your website is better then most books there and i would dare to say that i will stick to this site now rather then even masterpieces like Stephen’s Prata Primer

    The way you explain things with examples and actually sticking to important things without writting novels is something that just works great with my mind.

  • yogal

    Wow, great explanation of encapsulation, and WHY one would use getters/setters instead of directly accessing members!

    One good argument for using encapsulation might be validation. When you have setters set-up you can validate what is passed to members and take appropriate action. Although members have to be of certain type, which provides low-level validation, sometimes you need a more complex requirement!

    Take care and thanks for such a wonderful tutorial!

  • Henry

    Hmm when i ran the last example - i got like -858993460. Any ideas?

  • Balu Nair

    Hi Alex,

    Your article rocks buddy! This article is such a precious gem.


  • AsianBorat

    This tutorial is incredible. This article didn’t just explain encapsulation. It gave me a clear example, which FINALLY made me understand why encapsulation is so necessary.

  • yogendra

    great tutorial…..
    It gave me clear idea of what inheritance is and also
    the most basic difference between c and c++ is the
    code maintainability achieved through inheritance

  • DavidE

    Hey, I have a tip for those who like to consolidate their code. Instead of having both setValue() and getValue() methods, I do this:


    #ifndef GETSET_H
    #define GETSET_H

    enum GetOrSet{



    #include <iostream>
    #include <cstdlib>
    #include "getset.h"

    class Employee{
    char name[25];
    int ID;
    double wage;
    void setInfo(char *name, int ID, double wage){
    strncpy(Employee::name, name, 25);
    Employee::ID = ID;
    Employee::wage = wage;

    double Wage(GetOrSet option, double value=0){

    if(option == GET)
    return Employee::wage;
    else if (option == SET)
    Employee::wage = value;

    void toString(){
    std::cout << "Name:\t" << name << std::endl << "ID:\t" << ID << std::endl << "Wage:\t$" << wage;

    inline void pause(){

    std::cout << std::endl;

    int main(int argc, char* argv[]){

    Employee Alex;
    Alex.setInfo("Alex", 1, 38.00);
    Employee Jack;
    Jack.setInfo("Jack",2, 22.25);
    std::cout << std::endl;
    std::cout << std::endl;
    std::cout << Alex.Wage(GET);

    return 0;

  • Ramseena M.S

    Now too I didn’t understand the real usage of declaring class members private

  • Tonyv

    Great site, though a little less impressed by some of the arguements for access functions. Like, “what happens if one changes the name of a member…” well, what if you change the name of the access function? The debug arguement is better, but a bit arbitrary. Why not use the same argument to put redundant functions all over the place? Best was the string/length example, though only relevent when one has this sort of situation.

    A final grump: c++ is an intrinsicly hard to read language because so often what something means depends on the context. An amusing exercise would be to list all the things “*p” could mean. So while I appreciate the efforts made to improve the “readability” of c++, I read this often enough to think the author(s) consider c++ readability a feature rather than a curse. There are certainly ways to write Chinese to make it more readable, but that does not mean it is a language designed to be easily read.

  • Michael Exavery

    I face a problem on declaring a class with array attributes.


  • Rohan

    I have a problem in the following program…..(I am using turbo C++ i.e old version)

    output:Enter number: 10
    You entered: 10
    Now number changed to: -10

    Can you explain the above program? Especially why did we use ABC in passing reference to object?

    • alan


      February 1, 2015 at 7:57 am  · Reply

      Well you wouldn’t normally use a getter to actually prompt for data input, it
      is really to return a value to the user and not to output it to the screen.
      But except for a minor difference between compilers that function does work.

      Mainly you asked about why use ABC to pass a reference, its confusing because you call the function
      in main() as obj1.putdata() so it shouldn’t have compiled without an argument of type class ABC, though when modified as below
      it does work.
      In essence when you define a function with parameters you have to state the data type e.g. int, double, char etc.
      A class is a new data type defined by you.
      If you want a function to receive a class object by reference then you have to tell the function what to expect, hence
      "ABC &obj" just the same as if want a function to receive say an int by reference you would tell it "int &nNum"

      Hopefully that explains it, however I don’t think its what you really want to do, I’ve added
      another function "change_me()" which I think is what you were trying to do.

      Of course since you defined "int data" as public there is no need for a function anyway, as per my last example.
      #include <iostream>

      using namespace std;

      class ABC
      public:int data;
             void getdata()
                  cout << "Enter the number 10 ";
                 cin >> data; // VS 2013 doesn’t accept cout <>, but you missed the prompt anyway
                 cout << "You Entered:" << data;
             void putdata(ABC &obj)
                 cout << "Now number is changed to:" <<;
              void change_me()
                  data = data++ ;
                  cout << "Number is now: " << data ;

      void main()
          ABC obj1;
          obj1.putdata(obj1); // added obj1 as the argument
          cout << "Number is now: " <<;
      output:Enter number : 10
          You entered : 10
          Now number changed to : -10
          Number is now: -9
          Number is now: -8


  • Nikhil Mittal

    Alex, your tutorials are awesome! I am loving these. Thanx!

  • sandip patidar

    Very beautiful way to explain C++.
    You really did excellent Job. Keep it up!!!

  • trey

    Just for consistency’s sake, shouldn’t ‘Setters’ in the line where you explain access functions be emboldened like ‘Getters’ is?

  • Shivam Tripathi

    Hii..Alex..plzz help me out with this code…actually i want to enter some names and want to display those names which have "sh" contained in them…for eg:- if i give inputs "shivam" "shweta" "anil" "ravi" …then the program should print "shivam" "shweta" as O/P coz they have "sh" in their names…
    this code is compiling successfully but not giving desired O/P…plzz help

    • Hiii Shivam…

      1. There is a logic error in your for statement where you are taking input from the user.
      2. pCptr is assigned a whole array(e.g. Name[m]) and not an individual character. So, the statement if(pcPtr == "sh") will only evaluate to true if a whole string(name) is "sh".
      3. pCptr < Name[m] + 5 doesn’t make any sense to me.

      These are some errors I caught in your program. The problem you want to solve would better be solved with an array of strings I think.

      Here is my solution(using multidimensional array of chars):

      Not the best solution, but works… 😉

  • 1. "An access function is a short public function whose job is to return the value of a private member variable"

    According to this definition of access functions, only Getters fall into access function’s category (There definitions are the same) and setters, whose job is to set the value, is not an access function. This question(or confusion whatever) raised in my mind when I saw that both getters and access functions are exactly same.

    2. "For example, in the above mentioned String class, you might see something like this…."

      Where is the string class. Can you write the full String class, without that I have some confusions with                             the code:

    How one can tell that m_chString is pointing to a dynamically allocated string. I only see the definition of m_chString and there is no assignment or Initialization.

    Thanks…pretty excited in this chapter :-)

    • Alex

      1) Definition updated. Thanks for the feedback.
      2) I removed the words “above mentioned”. There’s no way to tell whether m_chString is pointed at a dynamically allocated string (it could be a null pointer). The comment is meant to show the intent of the variable, not it’s actual value.

  • Methos

    I’ve been using these lessons for a while and have done quite a bit of Get/Set functions in the project I’m working on, but have run into a snag. I’m trying to generate a maze to explore and as part of that, I have the following:

    (there’s more to that)

    And a series of functions like the following

    I say like, because I’ve already checked for typos and such (and corrected one unrelated error). Unfortunately, for some reason I cannot determine, SetIsActive() (which looks like that but with the correct variables) does nothing and SetIsPassable() is setting every bool member except m_bIsQuestBoss and m_bMonsterMoved to true. Which then for a variety of reasons stops the maze from being generated.

    I’m certain this is the issue as I’ve put cout statements in the maze generating code so I can monitor these values.

    Anyway I was wondering if you could think of anything that could cause this sort of weirdness. I changed IDE to code blocks in case it was a compiler problem (which maybe I have wrong as it wanted to look for more than one compiler when I installed it), but the error persists.

    • Methos

      Oy, nevermind.

      Apparently half of my Get() functions which were copypasted initially weren’t corrected to return the proper variable. Which I would have caught four days ago if I had searched for "passable" on the header file rather than other places I thought the Set function might have appeared.

    • Alex

      I don’t think I have enough information to effectively determine what this issue is. The only thing I see that’s weird is that your set function returns *this. Normally setters return void. Is your maze a 2d array of MazeTiles?

      • Methos

        The error was in my Getters, a bunch of them were returning m_bIsPassable instead of the variable I meant them to because I managed to copypaste them and change the function names and not the variables.

        The set function returns *this so I can chain a bunch of them on one line where appropriate, so for example in my maze creating function, I have the following

        I then start building the maze from where ever the entrance got put, the above code makes sure that tile is actually in the interior.

        Yes, my Maze is an array of MazeTiles of size Width * Length and sits inside of an object I call MazeData (Place is a MazeData object, pMap is a Maze object pointer) which has member variables for width, length, what direction the player is facing, how many monsters and traps are left, etc.

  • sheik

    This is wonderful. I never saw before this type of website to learn C++, thanks to all who made it

Leave a Comment




3 − three =

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