Publishers of technology books, eBooks, and videos for creative people

Home > Articles > Web Design & Development > PHP/MySQL/Scripting

This chapter is from the book

Classes

To define objects in C++, you create classes. Defining your own classes is actually easier than explaining it. So rather than starting with a long explanation, let's go through the sample program in Listing 3.1.

Example 3.1. Defining a software object with a C++ class

1    #include <cstdlib>
2    #include <iostream>
3
4    using namespace std;
5
6    class my_object
7    {
8    public:
9        int i;
10       float f;
11   };
12
13   int main(int argc, char *argv[])
14   {
15       my_object anObject;
16
17       anObject.i = 10;
18        anObject.f = 3.14159;
19
20       cout << "i = " << anObject.i << endl;
21       cout << "f = " << anObject.f << endl;
22       system("PAUSE");
23       return (EXIT_SUCCESS);
24  }

The short program in Listing 3.1 demonstrates how to define a class in C++. It uses the C++ keyword class on line 6 to define a new type: my_object. Everything in the class definition must be inside the opening and closing braces. The definition of the contents of the my_object type spans lines 7–11.

This program uses the my_object type to declare a variable in the main() function on line 13 As you can see, declaring a variable of type my_object is done in just the same way as declaring integers or floating-point numbers. Just as with any other variable type, variables of type my_object can be accessed in the functions where they are declared. Another way to say that is that the rules of scope work the same way for both objects and built-in types such as int.

Member Data

The my_object type contains an integer called i and a floating-point number called f. Programs using the my_object type store data in i and f. Therefore, i and f are collectively referred to as the class's member data. Confusingly, when we talk about just i or f by themselves, we call them data members. In other words, one item of member data is called a data member. And I'll bet you thought programmers had no sense of humor.

A class's member data stores all of the information that describes the object the class represents. As mentioned earlier, that information is also called the class's attributes.

The member data in the my_object class in Listing 3.1 is defined as being public. This means that any function can access the member data directly. For example, on line 17, the main() function stores an integer in i. It does so by stating the variable name (anObject), followed by a period, and then the data member name (i).

After storing values in the member data of the variable anObject, the program in Listing 3.1 prints the values it stored. When it does, line 20 shows that it uses anObject.i just as if it was a regular int variable. Specifically, it uses the insertion operator to put the value in anObject.i into the stream cout. On line 21, it does the same with anObject.f. Figure 3.1 shows the output.

03fig01.jpg

Figure 3.1 The output of the program in Listing 3.1.

As you can see, the program printed the values in anObject.i and anObject.f in just the way it prints integer or floating-point variables.

You can declare more than one object of the same type in a function. Listing 3.2 shows how.

Example 3.2. Declaring two objects of the same type in a function

1    #include <cstdlib>
2    #include <iostream>
3
4    using namespace std;
5
6    class my_object
7    {
8    public:
9        int i;
10       float f;
11   };
12
13   int main(int argc, char *argv[])
14   {
15       my_object anObject, anotherObject;
16
17       anObject.i = 10;
18       anObject.f = 3.14159;
19
20       anotherObject.i = -10;
21       anotherObject.f = 0.123456;
22
23        cout << "anObject.i = " << anObject.i << endl;
24       cout << "anObject.f = " << anObject.f << endl;
25
26       cout << "anotherObject.i = " << anotherObject.i << endl;
27       cout << "anotherObject.f = " << anotherObject.f << endl;
28
29       system("PAUSE");
30       return (EXIT_SUCCESS);
31  }
32

As the program in Listing 3.2 illustrates, you can declare as many objects of the same type as you need. Each object has its own member data, in this case i and f. The value in anObject.i has nothing to do with the value in anotherObject.i; they are completely independent of each other. The same is true for anObject.f and anotherObject.f. You can see this from the output of the program, which appears in Figure 3.2 .

03fig02.jpg

Figure 3.2 The values in the two objects are independent of each other.

In Figure 3.2, the program stores and prints two different sets of values. This shows that the two objects contain different information; they are independent of each other.

Member Functions

As mentioned earlier, programmers define more than just the data for the objects they create. When a game programmer creates a type, she also writes the set of operations that can be performed on the type. Those operations are functions, which we introduced in chapter 2. The functions that form the set of valid operations that can be performed on a type are all members of the class. Just as we can define member data in classes, we can also define member functions. Member functions form the set of valid operations a program can perform on an object. Again, it's easier to show what I mean rather than launching into a long explanation. So let's examine the program in Listing 3.3.

Example 3.3. Creating and using member functions

1    #include <cstdlib>
2    #include <iostream>
3
4    using namespace std;
5
6    class my_object
7    {
8    public:
9        void SetI(int iValue);
10       int GetI();
11
12       void SetF(float fValue);
13       float GetF();
14
15   private:
16       int i;
17       float f;
18   };
19
20
21   void my_object::SetI(int iValue)
22   {
23       i = iValue;
24   }
25
26
27   int my_object::GetI()
28   {
29       return (i);
30   }
31
32
33   void my_object::SetF(float fValue)
34   {
35       f = fValue;
36   }
37
38
39   float my_object::GetF()
40   {
41       return (f);
42   }
43
44
45   int main(int argc, char *argv[])
46   {
47       my_object anObject, anotherObject;
48
49       anObject.SetI(10);
50       anObject.SetF(3.14159);
51
52       anotherObject.SetI(-10);
53       anotherObject.SetF(0.123456);
54
55       cout << "anObject.i = " << anObject.GetI() << endl;
56       cout << "anObject.f = " << anObject.GetF() << endl;
57
58       cout << "anotherObject.i = " << anotherObject.GetI() << endl;
59       cout << "anotherObject.f = " << anotherObject.GetF() << endl;
60
61       system("PAUSE");
62       return (EXIT_SUCCESS);
63  }

The program in Listing 3.3 is a modification of the program in Listing 3.2. If you compare the two programs, you'll see some very important changes.

First, the program in Listing 3.3 changed the member data from public to private. You'll see this on lines 15–17. Recall that any function in a program can access public member data. The same is true for public member functions. However, private members are different. The private member data on lines 16 and 17 can only be accessed by member functions. It's as if the class is a very exclusive club; only members can use the club's private goodies.

The list of member functions is shown on lines 9–13. Notice that all of these functions are public. This is typically how programmers define classes. You should only rarely make member data publicly accessible. Normally, the member functions should be public and the member data private.

The reason programmers make class data private and functions public is simple: control. If a class's member data can only be accessed by the member functions, then we're controlling how the data can be changed. If the member functions never let the data get into an invalid state, then the data will always be valid.

Remember our dragon example we used when we first started talking about classes? Recall that the dragon in the game could eat fireberries to spit fire farther. Suppose the number of fireberries the dragon has eaten is stored in the dragon class as a data member. What would happen in the game if that number somehow got to be negative? Oops. Now the dragon swallows fire rather than spits it. The game will probably crash. That's why it's vital to keep all data valid at all times.

When we define objects, controlling the access to member data helps keep the data in a valid state. No functions outside the class can change private data. As long as the member functions never let the data become invalid, the data is always in a valid state. This is such an important point that I'm going to emphasize it with a special Tip.

If you look back at Listing 3.3, you'll see the prototypes for the member functions on lines 9–13. Putting the prototypes in the class tells the compiler which functions are members. The member functions for this class are very simple: All they do is set or get the values of the member data. We'll see in later chapters that member functions can also check the values before they set the member data.

The actual functions are given on lines 21–42. Let's focus on the first line of the SetI() function, which appears on line 21. Notice that the first line of the function includes the name of the class followed by two colons. Two colons used together like that—known as the C++ scope resolution operator—is a way to tell the compiler, "This is the function SetI() that I said was a member in the my_object class definition." The compiler replies, "Aha. So every time I see a call to the my_object class's SetI() function, this is the function I'll use." All member functions must be written in this way.

The SetI() function sets the value of i. You might be thinking, "Duh. I could tell that from the name of the function." That's exactly why the function is named SetI(). When you write your member functions, name them in a way that anyone looking at your code can tell what the function does by its name. If you try to explain what the function does, "Duh" is a good response to get—it means you named your function well.

As I mentioned, the SetI() function sets the value of i to the value in the iValue parameter. In most programs, the SetI() function would check the value of iValue before saving it into i. I'll show how to do that sort of data validation when we discuss if-else statements in "The if-else Statement" section later in this chapter.

Now take a look at the main() function in Listing 3.3. On lines 49–50, you'll see calls to the SetI() and SetF() functions. Notice that the program calls member functions by stating the name of the object, followed by a period, and then the name of the function. There is an important reason for doing it this way: If you look on lines 52–53, you'll see two more calls to the SetI() and SetF() functions. The difference between these two pairs of function calls is that the first pair sets the member data in the anObject variable, while the second pair sets the member data of the anotherObject variable. So any time you call a member function, you call that function on an object. The function uses the member data of that particular object and no other. This enables you to specifically state which object you're changing.

Lines 55–59 demonstrate calls to the GetI() and GetF() functions. Again, they follow the same pattern as calls to the SetI() and SetF() functions. Specifically, they state the variable name, then a period, and then the function name. Your programs always call member functions in this way.

Constructors and Destructors

Classes can have special member functions called constructors and destructors. Constructors are called automatically when the object is created. Constructors are used to initialize the object's member data into known states before any other function can possibly use the object. Destructors are called automatically when the object is destroyed. They perform any cleanup tasks on the object that may be required. Listing 3.4 demonstrates the use of constructors and destructors.

Example 3.4. Constructors and destructors in classes

1    #include <cstdlib>
2    #include <iostream>
3
4    using namespace std;
5
6    class my_object
7    {
8    public:
9        my_object();
10       ~my_object();
11
12       void SetI(int iValue);
13       int GetI();
14
15       void SetF(float fValue);
16       float GetF();
17
18   private:
19       int i;
20       float f;
21   };
22
23
24   my_object::my_object()
25   {
26       cout << "Entering constructor." << endl;
27       i = 0;
28       f = 0.0;
29   }
30
31
32   my_object::~my_object()
33   {
34       cout << "Entering destructor." << endl;
35   }
36
37
38   void my_object::SetI(int iValue)
39   {
40       i = iValue;
41   }
42
43
44   int my_object::GetI()
45   {
46       return (i);
47   }
48
49
50   void my_object::SetF(float fValue)
51   {
52       f = fValue;
53   }
54
55
56   float my_object::GetF()
57   {
58       return (f);
59   }
60
61
62   int main(int argc, char *argv[])
63   {
64       my_object anObject, anotherObject;
65
66       anObject.SetI(10);
67       anObject.SetF(3.14159);
68
69       anotherObject.SetI(-10);
70       anotherObject.SetF(0.123456);
71
72       cout << "anObject.i = " << anObject.GetI() << endl;
73       cout << "anObject.f = " << anObject.GetF() << endl;
74
75       cout << "anotherObject.i = " << anotherObject.GetI() << endl;
76       cout << "anotherObject.f = " << anotherObject.GetF() << endl;
77
78       system("PAUSE");
79       return (EXIT_SUCCESS);
80   }

Looking at lines 9–10 of Listing 3.4, you'll see that the my_object class now contains prototypes for two additional member functions: the constructor and the destructor, respectively. These prototypes are very different from any that we have introduced so far. Unlike other member functions, the names of constructors exactly match the name of the class. The only difference between the names of a constructor and a destructor is that the destructor name is preceded by the tilde (pronounced TILL-duh) character, which looks like this: "~".

The code for the constructor is on lines 24–29. Like all member functions, the constructor must state the class that it's a member of by using the class name and then the scope resolution operator. That's why line 24 has the name of the class, then the two colons followed by the name of the constructor (which is also the name of the class).

Notice that neither the constructor nor the destructor has a return type. The constructor doesn't need a return type because it creates an object of the class that it's a member of. In Listing 3.4, the constructor creates an object of type my_object. In "programmer-speak," we say that the constructor's return type is implicit in its name.

Destructors, on the other hand, delete an object of their class type. There is no return type because there's nothing to return. The object is gone when the destructor ends.

When the constructor starts, it prints the message Entering constructor to the screen. Most constructors don't do this; I did it here just for demonstration purposes. The primary purpose of a constructor is to set the member data into a known state when the program creates an object of that type. That's exactly what happens on lines 27–28 of Listing 3.4. The constructor sets the member data to 0.

The destructor appears on lines 32–35. This class has nothing to clean up, so the destructor doesn't do anything significant. For demonstration purposes, it prints the message Entering destructor when it starts.

A look at the main() function on lines 64–79 shows that it is no different than the one in Listing 3.3. That probably seems strange. The logical question to ask is, "Why aren't the constructor and destructor called?" In fact, they are. The program output in Figure 3.3 proves it.

03fig03.jpg

Figure 3.3 Calling the constructor and destructor.

When I ran the program in Listing 3.4, it began with the main() function, as all C++ programs do. The first thing main() did was to declare two variables of type my_object. At that time, the program automatically called the constructor once for each object that main() created. The first two lines of the output in Figure 3.3 show that that's exactly what happened; the constructor was called twice. Each time the constructor executed, it printed the message Entering constructor.

On lines 66–70, main() set the member data in both of its my_object variables. It then printed the values in the member data. We can see that in the output in Figure 3.3 The program paused and waited for me to press a key. When I did (just in case you're curious, I pressed the letter Z), the program executed the return statement on line 79. This caused the main() function to end. When main() ended, the two variables it declared on line 64 were no longer being used. Programmers say that the variables went "out of scope." When variables go out of scope, C++ programs automatically calls the appropriate destructors once for each class variable. In this case, it called the my_object destructor twice, as you can see from the output in Figure 3.3

Inline Member Functions

As you begin to read professional C++ programming literature, you'll see that many programmers put the code for their member functions into the class definitions. This approach is allowed in C++ programming. Functions defined this way are called inline member functions. listing 3.5 demonstrates the use of inline member functions.

Example 3.5. A class with inline member functions

1    #include <cstdlib>
2    #include <iostream>
3
4    using namespace std;
5
6    class point
7    {
8    public:
9        point()
10       {
11           x = y = 0;
12       }
13
14       void SetX(int xValue)
15       {
16           x = xValue;
17       }
18
19       int GetX(void)
20       {
21           return (x);
22       }
23
24       void SetY(int yValue)
25       {
26           y = yValue;
27       }
28
29       int GetY(void)
30       {
31           return (y);
32       }
33
34   private:
35       int x, y;
36   };
37
38   int main(int argc, char *argv[])
39   {
40       point rightHere;
41
42       rightHere.SetX(10);
43        rightHere.SetY(20);
44
45       cout << "(x,y)=(" << rightHere.GetX();
46       cout << "," << rightHere.GetY() << ")";
47       cout << endl;
48
49       rightHere.SetX(20);
50       rightHere.SetY(10);
51
52       cout << "(x,y)=(" << rightHere.GetX();
53       cout << "," << rightHere.GetY() << ")";
54       cout << endl;
55
56       system("PAUSE");
57       return (EXIT_SUCCESS);
58   }

Rather than just prototypes for member functions, the class in Listing 3.5 contains the member functions themselves. All of the code for each function appears in the class. The main() function on lines 38–58 demonstrates that your programs can use inline member functions in exactly the same way they use member functions defined outside of a class.

You're probably quite logically wondering what, if any, differences exist between inline and out-of-line member functions. There's really only one difference: When you define a member function inline, the compiler substitutes the code from the inline member function into your program. With out-of-line functions, that doesn't happen. For instance, if you look back at Listing 3.5, you'll see the statement

rightHere.SetX(10);

on line 42. When this statement gets compiled, the compiler substitutes the code for the SetX() function right into the statement. That is, it puts the equivalent of

rightHere.x=10;

into the compiled program. Of course, it doesn't change the source code in the .cpp file. It performs the substitution in the object code that it generates. It does this everywhere in every function that calls the inline function. The program in Listing 3.5 makes one call to the constructor, and two calls each to SetX() and SetY(). That means it substitutes code from the member functions into the main() function five times.

When I was teaching college-level C++ programming classes, students would often ask, "Why not just make all functions inline?"

The first reason is that the compiler won't allow it. If the compiler determines that the function is too long or too complex, it won't compile the member function as an inline function. It still compiles the function without a problem. However, it converts the member function into an out-of-line function in the compiled code. And it does this without telling you. It is completely up to whoever writes the compiler whether or not a function can be made inline. You and I can't control it. Writing functions inline is more of a suggestion than a command.

Usually functions remain inline if all they do is set or get values from members in a class. They generally also remain inline if they perform simple calculations. However, member functions that contain loops or call other functions are not likely to remain inline.

Another reason why it might not be a good idea to make all member functions inline is that inline member functions can make programs very large. Because the C++ compiler performs code substitution with inline member functions, there are fewer function calls in programs so they run faster. However, it also makes them bigger because the code for the inline functions gets inserted repeatedly. Using inline functions means that there are lots of copies of the inline function in the compiled program. With out-of-line functions, the program jumps to the one and only copy of the member function. That's a tiny bit slower, but it makes the program smaller. So when you're writing programs, you have to decide which is more important—speed or size.

The last reason why you might not make all of your member functions inline is that it makes your classes hard to read. Complex classes with lots of member functions become huge when you use inline member functions. Other programmers tend to find them difficult to deal with. Plenty of programmers disagree with this point of view—you have to decide for yourself.

One way to have the advantages of inline member functions without cluttering up your class definitions is to use out-of-line inline functions.

Say what?

Amazingly enough, C++ lets you define out-of-line member functions that are inline. It sounds kooky, but it's actually a nice feature. listing 3.6 illustrates how to create out-of-line inline functions.

Example 3.6. Making out-of-line functions inline

1    #include <cstdlib>
2    #include <iostream>
3
4    using namespace std;
5
6    class point
7    {
8    public:
9        point();
10       void SetX(int xValue);
11       int GetX(void);
12       void SetY(int yValue);
13       int GetY(void);
14
15   private:
16       int x,y;
17    };
18
19
20    inline point::point()
21    {
22       x = y = 0;
23    }
24
25    inline void point::SetX(int xValue)
26    {
27       x = xValue;
28    }
29
30    inline int point::GetX(void)
31    {
32       return (x);
33    }
34
35    inline void point::SetY(int yValue)
36    {
37       y = yValue;
38    }
39
40    inline int point::GetY(void)
41    {
42       return (y);
43    }
44
45
46
47    int main(int argc, char *argv[])
48    {
49        point rightHere;
50
51        rightHere.SetX(10);
52        rightHere.SetY(20);
53
54        cout << "(x,y)=(" << rightHere.GetX();
55        cout << "," << rightHere.GetY() << ")";
56        cout << endl;
57
58        rightHere.SetX(20);
59        rightHere.SetY(10);
60
61        cout << "(x,y)=(" << rightHere.GetX();
62        cout << "," << rightHere.GetY() << ")";
63        cout << endl;
64
65        system("PAUSE");
66        return (EXIT_SUCCESS);
67    }

In Listing 3.6, all of the functions from Listing 3.5 are now moved out of line. Only the function prototypes remain in the class definition. However, if you look at the member functions, you'll see that each one begins with the C++ keyword inline. An example is the SetX() function on line 25. Putting the keyword inline at the beginning of the function definition makes SetX() an inline function even though the code appears out of line. Using this style gives you shorter, more readable class definitions and still provides the advantages of inline functions. When we examine the source code for the LlamaWorks2D game engine in the next chapter (the source code is also provided on the CD), you'll find that this is the style it uses for nearly all of its inline functions.

Peachpit Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from Peachpit and its family of brands. I can unsubscribe at any time.

Overview


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about Peachpit products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information


To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.

Surveys

Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites; develop new products and services; conduct educational research; and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.

Newsletters

If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email ask@peachpit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information


Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.

Security


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.

Children


This site is not directed to children under the age of 13.

Marketing


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information


If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.

Choice/Opt-out


Users can always make an informed choice as to whether they should proceed with certain services offered by Adobe Press. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.peachpit.com/u.aspx.

Sale of Personal Information


Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents


California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure


Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.

Links


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact


Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice


We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020