Você está na página 1de 6

Using Namespaces

One of C++'s less heralded additions is addition of namespaces, which can be used to structure a program into "logical units". A namespace functions in the same way that a company division might function -- inside a namespace you include all functions appropriate for fulfilling a certain goal. For instance, if you had a program that connected to the Internet, you might have a namespace to handle all connection functions:
namespace net_connect { int make_connection(); int test_connection(); //so forth... }

You can then refer to functions that are part of a namespace by prefixing the function with the namespace name followed by the scope operator -- ::. For instance,
net_connect::make_connection()

By enabling this program structure, C++ makes it easier for you to divide up a program into groups that each perform their own separate functions, in the same way that classes or structs simplify object oriented design. But namespaces, unlike classes, do not require instantiation; you do not need an object to use a specific namespace. You only need to prefix the function you wish to call with namespace_name:: -- similar to how you would call a static member function of a class. Another convenience of namespaces is that they allow you to use the same function name, when it makes sense to do so, to perform multiple different actions. For instance, if you were implementing a low-level IO routine and a higher level IO routine that uses that lower level IO, you might want to have the option of having two different functions named "input" -- one that handles low-level keyboard IO and one that handles converting that IO into the proper data type and setting its value to a variable of the proper type. So far, when we've wanted to use a namespace, we've had to refer to the functions within the namespace by including the namespace identifier followed by the scope operator. You can, however, introduce an entire namespace into a section of code by using a usingdirective with the syntax
using namespace namespace_name;

Doing so will allow the programmer to call functions from within the namespace without having to specify the namespace of the function while in the current scope. (Generally, until the next closing bracket, or the entire file, if you aren't inside a block of code.) This convenience can be abused by using a namespace globally, which defeats some of the purpose of using a namespace. A common example of this usage is
using namespace std;

which grants access to the std namespace that includes C++ I/O objects cout and cin. Finally, you can introduce only specific members of a namespace using a usingdeclaration with the syntax
using namespace_name::thing;

One trick with namespaces is to use an unnamed namespace to avoid naming conflicts. To do so, simply declare a namespace with the normal syntax, but leave off the identifier; when this is done, you will have
namespace { //functions }

and within the namespace you are assured that no global names will conflict because each namespace's function names take precedence over outside function names. Now, you might ask, how can you actually use anything in that namespace? When your program is compiled, the "anonymous" namespace you have created will be accessible within the file you created it in. In effect, it's as though an additional "using" clause was included implicitly. This effectively limits the scope of anything in the namespace to the file level (so you can't call the functions in that namespace from another other file). This is comparable to the effect of the static keyword. Renaming namespaces Finally, if you just don't feel like typing the entire name of namespace, but you're trying to keep to a good style and not use the using keyword, you can rename a namespace to reduce the typing:
namespace <new> = <old>

Static: The Multipurpose Keyword


Most C++ keywords allow you to do one thing. You use int to declare an int, or that a function returns an int or expects an int as an argument. You use new to allocate memory, and delete to free memory. You use const to indicate that a variable's value cannot be changed. Ironically, the keyword static, though the word means "unchanging," has multiple (and apparently unrelated) uses. The keyword static can be used in three major contexts: inside a function, inside a class definition, and in front of a global variable inside a file making up a multifile program. The use of static inside a function is the simplest. It simply means that once the variable has been initialized, it remains in memory until the end of the program. You can think of it as saying that the variable sticks around, maintaining its value, until the program completely ends. For instance, you can use a static variable to record the number of times a function has been called simply by including the lines static int count =0; and count++; inside the function. Because count is a static variable, the line "static int count = 0;" will only be executed once. Whenever the function is called, count will have the last value assigned to it. You can also use static in this fashion to prevent a variable from being reinitialized inside a loop. For instance, in the following code, number_of_times comes out to be 100, even though the line "static int number_of_times = 0;" is inside the inner loop, where it would apparently be executed every time the program loops. The trick is that the keyword static prevents re-initialization of the variable. One feature of using a static keyword is that it happens to be initialized to zero automatically for you -- but don't rely on this behavior (it makes your intention unclear).
for(int x=0; x<10; x++) { for(int y=0; y<10; y++) { static int number_of_times = 0; number_of_times++; } }

You might use a static variable in order to preserve information about the last value a function returned, such as if you wanted to store the maximum value calculated by a function. If you are doing string parsing, you might also store the last token returned by the function in order to be able to fetch it simply by calling the function with an argument indicating it should return the last token. The second use of static is inside a class definition. While most variables declared inside a class occur on an instance-by-instance basis (which is to say that for each instance of a class, the variable can have a different value), a static member variable has the same value in any instance of the class and doesn't even require an instance of the class to exist. A helpful way to think about it is to imagine that the static variables of a class

contain information essential to the making of new member objects (as though a class definition were, to borrow an analogy from The Java Programming Language, a factory). For instance, if you wanted to number your instances of a class, you could use a static member variable to keep track of the last number used. Importantly, it is good syntax to refer to static member functions through the use of a class name (class_name::x; rather than instance_of_class.x;). Doing so helps to remind the programmer that static member variables do not belong to a single instance of the class and that you don't need to have a single instance of a class to use a static member variable. As you have probably noticed, to access the static member, you use the scope operator, ::, when you refer to it through the name of the class. An important detail to keep in mind when debugging or implementing a program using a static class member is that you cannot initialize the static class member inside of the class. In fact, if you decide to put your code in a header file, you cannot even initialize the static variable inside of the header file; do it in a .cpp file instead. Moreover, you are required to initialize the static class member or it will not be in scope. (The syntax is a bit weird: "type class_name::static_variable = value".) You can also have static member functions of a class. Static member functions are functions that do not require an instance of the class, and are called the same way you access static member variables -- with the class name rather than a variable name. (E.g. a_class::static_function(); rather than an_instance.function();) Static member functions can only operate on static members, as they do not belong to specific instances of a class. Static member functions can be used to modify static member variables to keep track of their values -- for instance, you might use a static member function if you chose to use a counter to give each instance of a class a unique id. For instance, you could use the following code:
class user { private: int id; static int next_id; public: static int next_user_id() { next_id++; return next_id; } /* More stuff for the class user */ user() {id = user::next_id++; //or, id = user.next_user_id(); } }; int user::next_id = 0;

Notice that you must include the type of the static variable when you set it! The line
user a_user;

would set id to the next id number not assigned to any other user through this process. Note that it would be good style to declare id as a const.

Static members
A class can contain static members, either data or functions. Static data members of a class are also known as "class variables", because there is only one unique value for all the objects of that same class. Their content is not different from one object of this class to another. For example, it may be used for a variable within a class that can contain a counter with the number of objects of that class that are currently allocated, as in the following example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 // static members in classes #include <iostream> using namespace std; class CDummy { public: static int n; CDummy () { n++; }; ~CDummy () { n--; }; }; int CDummy::n=0; int main () { CDummy a; CDummy b[5]; CDummy * c = new CDummy; cout << a.n << endl; delete c; cout << CDummy::n << endl; return 0; } 7 6

In fact, static members have the same properties as global variables but they enjoy class scope. For that reason, and to avoid them to be declared several times, we can only include the prototype (its declaration) in the class declaration but not its definition (its initialization). In order to initialize a static data-member we must include a formal definition outside the class, in the global scope, as in the previous example:
int CDummy::n=0;

Because it is a unique variable value for all the objects of the same class, it can be referred to as a member of any object of that class or even directly by the class name (of course this is only valid for static members):

1 cout << a.n; 2 cout << CDummy::n;

These two calls included in the previous example are referring to the same variable: the static variable n within class CDummy shared by all objects of this class. Once again, I remind you that in fact it is a global variable. The only difference is its name and possible access restrictions outside its class. Just as we may include static data within a class, we can also include static functions. They represent the same: they are global functions that are called as if they were object members of a given class. They can only refer to static data, in no case to non-static members of the class, as well as they do not allow the use of the keyword this, since it makes reference to an object pointer and these functions in fact are not members of any object but direct members of the class.

Você também pode gostar