19.4.1. Pointers to Data Members

As with any pointer, we declare a pointer to member using a * to indicate that the name we’re declaring is a pointer. Unlike ordinary pointers, a pointer to member also incorporates the class that contains the member. Hence, we must precede the * with classname:: to indicate that the pointer we are defining can point to a member of classname. For example:

// pdata can point to a string member of a const (or non const) Screen object
const string Screen::*pdata;

declares that pdata is a “pointer to a member of class Screen that has type const string.” The data members in a const object are themselves const. By making our pointer a pointer to const string member, we say that we can use pdata to point to a member of any Screen object, const or not. In exchange we can use pdata to read, but not write to, the member to which it points.

When we initialize (or assign to) a pointer to member, we say to which member it points. For example, we can make pdata point to the contents member of an unspecified Screen object as follows:

pdata = &Screen::contents;

Here, we apply the address-of operator not to an object in memory but to a member of the class Screen.

Of course, under the new standard, the easiest way to declare a pointer to member is to use auto or decltype:

auto pdata = &Screen::contents;

Using a Pointer to Data Member

It is essential to understand that when we initialize or assign a pointer to member, that pointer does not yet point to any data. It identifies a specific member but not the object that contains that member. We supply the object when we dereference the pointer to member.

Analogous to the member access operators, . and ->, there are two pointer-to-member access operators, .* and ->*, that let us supply an object and dereference the pointer to fetch a member of that object:

Screen myScreen, *pScreen = &myScreen;
// .* dereferences pdata to fetch the contents member from the object myScreen
auto s = myScreen.*pdata;
// ->* dereferences pdata to fetch contents from the object to which pScreen points
s = pScreen->*pdata;

Conceptually, these operators perform two actions: They dereference the pointer to member to get the member that we want; then, like the member access operators, they fetch that member from an object (.*) or through a pointer (->*).

A Function Returning a Pointer to Data Member

Normal access controls apply to pointers to members. For example, the contents member of Screen is private. As a result, the use of pdata above must have been inside a member or friend of class Screen or it would be an error.

Because data members are typically private, we normally can’t get a pointer to data member directly. Instead, if a class like Screen wanted to allow access to its contents member, it would define a function to return a pointer to that member:

class Screen {
public:
    // data is a static member that returns a pointer to member
    static const std::string Screen::*data()
        { return &Screen::contents; }
    // other members as before
};

Here we’ve added a static member to class Screen that returns a pointer to the contents member of a Screen. The return type of this function is the same type as our original pdata pointer. Reading the return type from right to left, we see that data returns a pointer to a member of class Screen that is a string that is const. The body of the function applies the address-of operator to the contents member, so the function returns a pointer to the contents member of Screen.

When we call data, we get a pointer to member:

// data() returns a pointer to the contents member of class Screen
const string Screen::*pdata = Screen::data();

As before, pdata points to a member of class Screen but not to actual data. To use pdata, we must bind it to an object of type Screen

// fetch the contents of the object named myScreen
auto s = myScreen.*pdata;


Exercises Section 19.4.1

Exercise 19.11: What is the difference between an ordinary data pointer and a pointer to a data member?

Exercise 19.12: Define a pointer to member that can point to the cursor member of class Screen. Fetch the value of Screen::cursor through that pointer.

Exercise 19.13: Define the type that can represent a pointer to the bookNo member of the Sales_data class.


..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset