1. Trang chủ
  2. » Công Nghệ Thông Tin

Absolute C++ (4th Edition) part 48 docx

10 228 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 148,07 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

For example, the function declaration and function definition in the namespace Space1 can be made available with the using directive using namespace Space1 as illustrated in Display 11.5

Trang 1

Note that you can have any number of these namespace groupings for a single namespace In Display 11.5, we used two namespace groupings for namespace Space1

and two other groupings for namespace Space2

Every name defined in a namespace is available inside the namespace groupings, but the names can also be made available to code outside the namespace groupings For example, the function declaration and function definition in the namespace Space1 can

be made available with the using directive

using namespace Space1

as illustrated in Display 11.5

Display 11.5 Namespace Demonstration (part 2 of 2)

26

27 namespace Space1

28 {

29 void greeting( )

30 {

31 cout << "Hello from namespace Space1.\n";

32 }

33 }

34 namespace Space2

35 {

36 void greeting( )

37 {

38 cout << "Greetings from namespace Space2.\n";

39 }

40 }

41 void bigGreeting( )

42 {

43 cout << "A Big Global Hello!\n";

44 }

S AMPLE D IALOGUE

Greetings from namespace Space2.

Hello from namespace Space1.

A Big Global Hello!

Trang 2

Self-Test Exercises

6 Consider the program shown in Display 11.5 Could we use the name greeting in place

of bigGreeting?

7 In Exercise 6, we saw that you could not add a definition for the following function to the

global namespace:

void greeting( );

Can you add a definition for the following function declaration to the global namespace? void greeting( int howMany );

This subsection describes a way to qualify a single name so that you can make only one name from a namespace available to your program, rather than making all the names in

a namespace available We saw this technique in Chapter 1 and so this is a review and amplification of what we said in Chapter 1

Suppose you are faced with the following situation You have two namespaces, NS1

and NS2 You want to use the function fun1 defined in NS1 and the function fun2

defined in namespace NS2 The complication is that both NS1 and NS2 also define a function myFunction (Assume all functions in this discussion take no arguments, so overloading does not apply.) There is a problem with

using namespace NS1;

using namespace NS2;

PUTTING A DEFINITION IN A NAMESPACE

You place a name definition in a namespace by placing it in a namespace grouping, which has the following syntax:

namespace Namespace_Name

{ Definition_1

Definition_2

Definition_Last

}

You can have multiple namespace groupings (even in multiple files), and all the definitions in all the groupings will be in the same namespace.

Trang 3

This would potentially provide conflicting definitions for myFunction (If the name

myFunction is never used, then most compilers will not detect the problem and will

allow your program to compile and run.)

What you need is a way to say you are using fun1 in namespace NS1 and fun2 in

namespace NS2 and nothing else in the namespaces NS1 and NS2 We have already been

using a technique that can handle this situation The following is your solution:

using NS1::fun1;

using NS2::fun2;

A qualification of the form

using Name_Space :: One_Name ;

makes the (definition of the) name One_Name from the namespace Name_Space available, but

does not make any other names in Name_Space available This is called a using declaration.

Note that the scope resolution operator :: that we use in these using declarations is

the same as the scope resolution operator we use when defining member functions

These two uses of the scope resolution operator have a similarity For example, Display

11.2 had the following function definition:

void DigitalTime::advance(int hoursAdded, int minutesAdded)

{

hour = (hour + hoursAdded)%24;

advance(minutesAdded);

}

In this case the :: means that we are defining the function advance for the class

Digi-talTime, as opposed to any other function named advance in any other class Similarly,

using NS1::fun1;

means we are using the function named fun1 as defined in the namespace NS1, as

opposed to any other definition of fun1 in any other namespace

There are two differences between a using declaration, such as

using std::cout;

and a using directive such as

using namespace std;

The differences are:

1 A a using declaration makes only one name in the namespace available to your

code, while a using directive makes all the names in a namespace available

2 A using declaration introduces a name (like cout) into your code so no other use of

the name can be made However, a using directive only potentially introduces the

names in the namespace

using NS1::fun1;

using

declaration

Trang 4

Point 1 is pretty obvious Point 2 has some subtleties For example, suppose the namespaces NS1 and NS2 both provide definitions for myFunction, but have no other name conflicts, then the following will produce no problems:

using namespace NS1;

using namespace NS2;

provided that (within the scope of these directives) the conflicting name myFunction is never used in your code

On the other hand, the following is illegal, even if the function myFunction is never used: using NS1::myFunction;

using NS2::myFunction;

Sometimes this subtle point can be important, but it does not impinge on most rou-tine code So, we will often use the term using directive loosely to mean either a using

directive or a using declaration

This section introduces a way to qualify names that we have not discussed before Suppose that you intend to use the name fun1 as defined in the namespace NS1, but you only intend to use it one time (or a small number of times) You can name the function (or other item) using the name of the namespace and the scope resolution operator as follows:

NS1::fun1( );

This form is often used when specifying a parameter type For example, consider int getInput(std::istream inputStream)

.

In the function getInput, the parameter inputStream is of type istream, where

istream is defined as in the std namespace If this use of the type name istream is the only name you need from the std namespace (or if all the names you need are similarly qualified with std::), then you do not need

using namespace std;

or using std::istream;

Note that you can use std::istream even within the scope of a using directive for another namespace which also defines the name istream In this case std::istream

and istream will have different definitions For example, consider using namespace MySpace;

void someFunction(istream p1, std::istream p2);

using

directive

Trang 5

Self-Test Exercises

Assuming istream is a type defined in the namespace MySpace, then p1 will have the type istream as defined in MySpace and p2 will have the type istream as defined in the

std namespace

8 What is the output produced by the following program?

#include <iostream>

using namespace std;

namespace Hello {

void message( );

} namespace GoodBye {

void message( );

} void message( );

int main( ) {

using GoodBye::message;

{ using Hello::message;

message( );

GoodBye::message( );

} message( );

return 0;

} void message( ) {

cout << "Global message.\n";

} namespace Hello {

void message( ) {

Trang 6

Example

cout << "Hello.\n";

} } namespace GoodBye {

void message( ) {

cout << "Good-Bye.\n";

} }

9 Write the declaration (prototype) for a void function named wow The function wow has two parameters, the first of type speed as defined in the speedway namespace and the sec-ond of type speed as defined in the indy500 namespace

A C LASS D EFINITION IN A N AMESPACE

In Displays 11.6 and 11.7 we have again rewritten both the header file dtime.h for the class Digi-talTime and the implementation file for the class DigitalTime This time (no pun intended),

we have placed the definition in a namespace called DTimeSavitch Note that the namespace

DTimeSavitch spans the two files dtime.h and dtime.cpp A namespace can span multiple files.

If you rewrite the definition of the class DigitalTime as shown in Displays 11.6 and 11.7, then the application file in Display 11.3 needs to specify the namespace DTimeSavitch in some way, such

as the following:

using namespace DTimeSavitch;

or using DTimeSavitch::DigitalTime;

C HOOSING A N AME FOR A N AMESPACE

It is a good idea to include your last name or some other unique string in the names of your namespaces so as to reduce the chance that somebody else will use the same namespace name

as you do With multiple programmers writing code for the same project, it is important that namespaces that are meant to be distinct really do have distinct names Otherwise, you can easily have multiple definitions of the same names in the same scope That is why we included the name

Savitch in the namespace DtimeSavitch in Display 11.9.

Trang 7

Display 11.6 Placing a Class in a Namespace (Header File)

1 //This is the header file dtime.h

2 #ifndef DTIME_H

3 #define DTIME_H

4 #include <iostream>

5 using std::istream;

6 using std::ostream;

7 namespace DTimeSavitch

8 {

9

10 class DigitalTime

11 {

12

13 <The definition of the class DigitalTime is the same as in Display 11.1.>

14 };

15

16 }// DTimeSavitch

17 #endif //DTIME_H

A better version of this class definition will be given in Displays 11.8 and 11.9.

Note that the namespace DTimeSavitch spans two files The other is shown in Display 11.7.

Display 11.7 Placing a Class in a Namespace (Implementation File)

1 //This is the implementation file dtime.cpp.

2 #include <iostream>

3 #include <cctype>

4 #include <cstdlib>

5 using std::istream;

6 using std::ostream;

7 using std::cout;

8 using std::cin;

9 #include "dtime.h"

10 namespace DTimeSavitch

11 {

12

13 <All the function definitions from Display 11.2 go here.>

14

15 }// DTimeSavitch

You can use the single using directive using namespace std;

in place of these four using declarations

However, the four using declarations are a preferable style.

Trang 8

UNNAMED NAMESPACES

A compilation unit is a file, such as a class implementation file, along with all the files

that are #included in the file, such as the interface header file for the class Every com-pilation unit has an unnamed namespace A namespace grouping for the unnamed namespace is written in the same way as for any other namespace, but no name is given, as in the following example:

namespace {

void sampleFunction( ) .

} //unnamed namespace

All the names defined in the unnamed namespace are local to the compilation unit, and so the names can be reused for something else outside the compilation unit For example, Displays 11.8 and 11.9 show a rewritten (and final) version of the interface

compilation

unit

Display 11.8 Hiding the Helping Functions in a Namespace (Interface File) (part 1 of 2)

1 //This is the header file dtime.h This is the interface for the class DigitalTime.

2 //Values of this type are times of day The values are input and output in 24-hour

3 //notation, as in 9:30 for 9:30 AM and 14:45 for 2:45 PM.

4 #ifndef DTIME_H

5 #define DTIME_H

6 #include <iostream>

7 using std::istream;

8 using std::ostream;

9 namespace DTimeSavitch

10 {

11 class DigitalTime

12 {

13 public :

14 DigitalTime( int theHour, int theMinute);

15 DigitalTime( );

16 //Initializes the time value to 0:00 (which is midnight).

17 getHour( ) const ;

18 getMinute( ) const ;

19 void advance( int minutesAdded);

20 //Changes the time to minutesAdded minutes later.

This is our final version of the class DigitalTime

This is the best version and the one you should use

The implementation to use with this interface is given in Display 11.9.

Trang 9

Display 11.8 Hiding the Helping Functions in a Namespace (Interface File) (part 2 of 2)

21 void advance( int hoursAdded, int minutesAdded);

22 //Changes the time to hoursAdded hours plus minutesAdded minutes later.

23 friend bool operator ==( const DigitalTime& time1,

24 const DigitalTime& time2);

25 friend istream& operator >>(istream& ins, DigitalTime& theObject);

26 friend ostream& operator <<(ostream& outs,

27 const DigitalTime& theObject);

28 private :

29 int hour;

30 int minute;

31 };

32 } //DTimeSavitch

33 #endif //DTIME_H

Note that the helping functions are not mentioned in the interface file

Display 11.9 Hiding the Helping Functions in a Namespace (Implementation File) (part 1 of 3)

1 //This is the implementation file dtime.cpp of the class DigitalTime.

2 //The interface for the class DigitalTime is in the header file dtime.h.

3 #include <iostream>

4 #include <cctype>

5 #include <cstdlib>

6 using std::istream;

7 using std::ostream;

8 using std::cout;

9 using std::cin;

10 #include "dtime.h"

11 namespace

12 {

13 int digitToInt( char c)

14 {

15 return ( int (c) - int (’0’) );

16 }

17 //Uses iostream, cctype, and cstdlib:

18 void readMinute(int& theMinute)

19 {

20 char c1, c2;

21 cin >> c1 >> c2;

22 if (!(isdigit(c1) && isdigit(c2)))

23 {

24 cout << "Error: illegal input to readMinute\n";

Specifies the unnamed namespace

Names defined in the unnamed namespace are local to the compilation unit So, these helping functions are local to the file dtime.cpp.

Trang 10

Display 11.9 Hiding the Helping Functions in a Namespace (Implementation File) (part 2 of 3)

25 exit(1);

26 }

27 theMinute = digitToInt(c1)*10 + digitToInt(c2);

28 if (theMinute < 0 || theMinute > 59)

29 {

30 cout << "Error: illegal input to readMinute\n";

31 exit(1);

32 }

33 }

34

35 //Uses iostream, cctype, and cstdlib:

36 void readHour( int & theHour)

37 {

38 char c1, c2;

39 cin >> c1 >> c2;

40 if ( !( isdigit(c1) && (isdigit(c2) || c2 == ’:’ ) ) )

41 {

42 cout << "Error: illegal input to readHour\n";

43 exit(1);

45 if (isdigit(c1) && c2 == ’:’)

46 {

47 theHour = digitToInt(c1);

48 }

49 else //(isdigit(c1) && isdigit(c2))

51 theHour = digitToInt(c1)*10 + digitToInt(c2);

52 cin >> c2; //discard ’:’

53 if (c2 != ’:’)

54 {

55 cout << "Error: illegal input to readHour\n";

56 exit(1);

59 if (theHour == 24)

60 theHour = 0; //Standardize midnight as 0:00.

61 if ( theHour < 0 || theHour > 23 )

62 {

Ngày đăng: 04/07/2014, 05:21

TỪ KHÓA LIÊN QUAN