Search

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”.

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
Index
8.3 -- Public vs private access specifiers

23 comments to 8.4 — Access functions and encapsulation

  • WONDERFUL TUTORIAL BY MR.ALEX...

  • Michael Exavery

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

  • 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.

  • Ramseena M.S

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

  • 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:

    getset.h:

    #ifndef GETSET_H
    #define GETSET_H

    enum GetOrSet{
    GET,
    SET
    };

    #endif

    main.cpp

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

    class Employee{
    public:
    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;
    system("PAUSE");
    }

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

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

    pause();
    return 0;
    }

  • 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

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">