- Software Objects
- Classes
- Logical Operators
- The If-Else Statement
- Namespaces and Scope Resolution
- A Brief Word About Structures
- Summary
Namespaces and Scope Resolution
In C++, the name of every class in a program has to be unique; there can't be two classes with the same name. This presents a potential problem. Suppose you write a game that uses the LlamaWorks2D library. LlamaWorks2D contains a class called vector, which I'll present in chapter 5, "Function and Operator Overloading." Games contain a lot of math. Imagine that you decide that you will also use a math library written by someone else in your game. It's very likely that the math library also contains a class called vector. When your game declares a variable of type vector, which class should the compiler use, the one in LlamaWorks2D or the one in the math library?
C++ provides a solution to the problem of conflicting class names: namespaces. A namespace is a way of grouping related classes together. In fact, it can be used for more than classes. Namespaces group related types, functions, and other kinds of C++ constructs that I'll discuss later. You create a namespace with the namespace keyword, as shown in Listing 3.9.
Example 3.9. Defining a namespace
1 #include <cstdlib> 2 #include <iostream> 3 4 using namespace std; 5 6 // Beginning of first namespace. 7 namespace anamespace 8 { 9 10 class point 11 { 12 public: 13 point() 14 { 15 x = y = 0; 16 } 17 18 void SetX(int xValue) 19 { 20 x = xValue; 21 } 22 23 int GetX(void) 24 { 25 return (x); 26 } 27 28 void SetY(int yValue) 29 { 30 y = yValue; 31 } 32 33 int GetY(void) 34 { 35 return (y); 36 } 37 38 private: 39 int x,y; 40 }; 41 42 // End of first namespace. 43 }; 44 45 46 47 // Beginning of second namespace. 48 49 namespace anothernamespace 50 { 51 class point 52 { 53 public: 54 point() 55 { 56 x = y = 0; 57 } 58 59 void SetX(int xValue) 60 { 61 x = xValue; 62 } 63 64 int GetX(void) 65 { 66 return (x); 67 } 68 69 void SetY(int yValue) 70 { 71 y = yValue; 72 } 73 74 int GetY(void) 75 { 76 return (y); 77 } 78 79 void Reset() 80 { 81 x = y = 0; 82 } 83 84 private: 85 int x,y; 86 }; 87 88 // End of second namespace. 89 90 }; 91 92 93 94 int main(int argc, char *argv[]) 95 { 96 anamespace::point rightHere; 97 98 rightHere.SetX(10); 99 rightHere.SetY(20); 100 101 cout << "(x,y)=(" << rightHere.GetX(); 102 cout << "," << rightHere.GetY() << ")"; 103 cout << endl; 104 105 anothernamespace::point rightThere; 106 rightThere.SetX(20); 107 rightThere.SetY(10); 108 109 cout << "(x,y)=(" << rightThere.GetX(); 110 cout << "," << rightThere.GetY() << ")"; 111 cout << endl; 112 113 rightThere.Reset(); 114 115 cout << "(x,y)=(" << rightThere.GetX(); 116 cout << "," << rightThere.GetY() << ")"; 117 cout << endl; 118 119 system("PAUSE"); 120 return (EXIT_SUCCESS); 121 }
This sample program defines two namespaces: one called anamespace and the other called anothernamespace. Both namespaces contain a class called point. If you examine the two classes, you'll find that they're nearly identical. The difference is that the point class in anothernamespace has a member function called Reset(). The point class in anamespace doesn't have that member function.
The program in Listing 3.9 uses both point classes without a problem. The compiler can tell which point class is being referred to because the main() function uses the scope resolution operator, which is the double colon (::). You see it on lines 96 and 105. On line 96, the main() function states that it is declaring a variable of type point and using the point class in the namespace called anamespace. Line 105 also declares a variable of type point, but it is the point class in the namespace called anothernamespace.
Every time you declare a variable that uses a type from a namespace, you must use the scope resolution operator. This makes your code really wordy. Most programmers don't care for this. The way you get around it is to put the using keyword into your program. On line 4 of Listing 3.9, you can see an example of the using statement. This line specifies that the program is using a namespace called std. The std namespace is defined by the C++ Standard Libraries in the file iostream, which is included on line 2. Pretty much all of the programs presented so far have used this namespace; most C++ programs do.
When you start using the LlamaWorks2D game engine, you'll see that all of its types are defined in a namespace called llamaworks2d. As a result, you'll put the statement
using namespace llamaworks2d;
at the beginning of your source code for your games. Having the using statement at the beginning of your files means that you can use types that LlamaWorks2D provides, such as vector, without having to specify llamaworks2d::vector throughout your code. If you use a vector class from another library, that's okay. Any time there's a conflict, you can resolve it by using the scope resolution operator to specify exactly which vector class you mean.