Главная » Просмотр файлов » B. Stroustrup - The C++ Programming Language

B. Stroustrup - The C++ Programming Language (794319), страница 88

Файл №794319 B. Stroustrup - The C++ Programming Language (B. Stroustrup - The C++ Programming Language) 88 страницаB. Stroustrup - The C++ Programming Language (794319) страница 882019-05-09СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 88)

For example:namespace N {struct S { int i };void f(S);void g(S);void h(int);}Section 14.2.4Argument-Dependent Lookup397struct Base {void f(N::S);};struct D : Base {void mf();void g(N::S x){f(x);// call Base::f()mf(x);// call D::mf()h(1);// error: no h(int) available}};In the standard, the rules for argument-dependent lookup are phrased in terms of associated namespaces (§iso.3.4.2).

Basically:• If an argument is a class member, the associated namespaces are the class itself (includingits base classes) and the class’s enclosing namespaces.• If an argument is a member of a namespace, the associated namespaces are the enclosingnamespaces.• If an argument is a built-in type, there are no associated namespaces.Argument-dependent lookup can save a lot of tedious and distracting typing, but occasionally it cangive surprising results. For example, the search for a declaration of a function f() does not have apreference for functions in a namespace in which f() is called (the way it does for functions in aclass in which f() is called):namespace N {template<class T>void f(T, int); // N::f()class X { };}namespace N2 {N::X x;void f(N::X, unsigned);void g(){f(x,1);}// calls N::f(X,int)}It may seem obvious to choose N2::f(), but that is not done.

Overload resolution is applied and thebest match is found: N::f() is the best match for f(x,1) because 1 is an int rather than an unsigned.Conversely, examples have been seen where a function in the caller’s namespace is chosen but theprogrammer expected a better function from a known namespace to be used (e.g., a standard-libraryfunction from std). This can be most confusing. See also §26.3.6.398NamespacesChapter 1414.2.5 Namespaces Are OpenA namespace is open; that is, you can add names to it from several separate namespace declarations.

For example:namespace A {int f();// now A has member f()}namespace A {int g();// now A has two members, f() and g()}That way, the members of a namespace need not be placed contiguously in a single file. This canbe important when converting older programs to use namespaces. For example, consider a headerfile written without the use of namespaces:// my header:void mf();void yf();int mg();// ...// my function// your function// my functionHere, we have (unwisely) just added the declarations needed without concerns of modularity.

Thiscan be rewritten without reordering the declarations:// my header:namespace Mine {void mf();// my function// ...}void yf();// your function (not yet put into a namespace)namespace Mine {int mg();// my function// ...}When writing new code, I prefer to use many smaller namespaces (see §14.4) rather than puttingreally major pieces of code into a single namespace. However, that is often impractical when converting major pieces of software to use namespaces.Another reason to define the members of a namespace in several separate namespace declarations is that sometimes we want to distinguish parts of a namespace used as an interface from partsused to support easy implementation; §14.3 provides an example.A namespace alias (§14.4.2) cannot be used to re-open a namespace.Section 14.3Modularization and Interfaces39914.3 Modularization and InterfacesAny realistic program consists of a number of separate parts.

For example, even the simple ‘‘Hello,world!’’ program involves at least two parts: the user code requests Hello, world! to be printed, andthe I/O system does the printing.Consider the desk calculator example from §10.2. It can be viewed as composed of five parts:[1] The parser, doing syntax analysis: expr(), term(), and prim()[2] The lexer, composing tokens out of characters: Kind, Token, Token_stream, and ts[3] The symbol table, holding (string,value) pairs: table[4] The driver: main() and calculate()[5] The error handler: error() and number_of_errorsThis can be represented graphically:drivererror handlerparserlexersymbol tablewhere an arrow means ‘‘using.’’ To simplify the picture, I have not represented the fact that everypart relies on error handling.

In fact, the calculator was conceived as three parts, with the driverand error handler added for completeness.When one module uses another, it doesn’t need to know everything about the module used. Ideally, most of the details of a module are unknown to its users. Consequently, we make a distinctionbetween a module and its interface. For example, the parser directly relies on the lexer’s interface(only), rather than on the complete lexer. The lexer simply implements the services advertised inits interface. This can be presented graphically like this:drivererror handlerparser interfaceparser implementationlexer interfacelexer implementationsymbol table interfacesymbol table implementationA dashed line means ‘‘implements.’’ I consider this to be the real structure of the program, and ourjob as programmers is to represent this faithfully in code.

That done, the code will be simple, efficient, comprehensible, maintainable, etc., because it will directly reflect our fundamental design.400NamespacesChapter 14The following subsections show how the logical structure of the desk calculator program can bemade clear, and §15.3 shows how the program source text can be physically organized to takeadvantage of it. The calculator is a tiny program, so in ‘‘real life’’ I wouldn’t bother using namespaces and separate compilation (§2.4.1, §15.1) to the extent done here.

Making the structure ofthe calculator explicit is simply an illustration of techniques useful for larger programs withoutdrowning in code. In real programs, each ‘‘module’’ represented by a separate namespace willoften have hundreds of functions, classes, templates, etc.Error handling permeates the structure of a program. When breaking up a program into modules or (conversely) when composing a program out of modules, we must take care to minimizedependencies between modules caused by error handling. C++ provides exceptions to decouple thedetection and reporting of errors from the handling of errors (§2.4.3.1, Chapter 13).There are many more notions of modularity than the ones discussed in this chapter and the next.For example, we might use concurrently executing and communicating tasks (§5.3, Chapter 41) orprocesses to represent important aspects of modularity.

Similarly, the use of separate address spaces and the communication of information between address spaces are important topics not discussed here. I consider these notions of modularity largely independent and orthogonal. Interestingly, in each case, separating a system into modules is easy. The hard problem is to provide safe,convenient, and efficient communication across module boundaries.14.3.1 Namespaces as ModulesA namespace is a mechanism for expressing logical grouping. That is, if some declarations logically belong together according to some criteria, they can be put in a common namespace toexpress that fact. So we can use namespaces to express the logical structure of our calculator. Forexample, the declarations of the parser from the desk calculator (§10.2.1) may be placed in a namespace Parser:namespace Parser {double expr(bool);double prim(bool get) { /* ... */ }double term(bool get) { /* ...

*/ }double expr(bool get) { /* ... */ }}The function expr() must be declared first and then later defined to break the dependency loopdescribed in §10.2.1.The input part of the desk calculator could also be placed in its own namespace:namespace Lexer {enum class Kind : char { /* ...

*/ };class Token { /* ... */ };class Token_stream { /* ... */ };Token_stream ts;}The symbol table is extremely simple:Section 14.3.1Namespaces as Modules401namespace Table {map<string,double> table;}The driver cannot be completely put into a namespace because the language rules require main() tobe a global function:namespace Driver {void calculate() { /* ... */ }}int main() { /* ...

*/ }The error handler is also trivial:namespace Error {int no_of_errors;double error(const string& s) { /* ... */ }}This use of namespaces makes explicit what the lexer and the parser provide to a user. Had Iincluded the source code for the functions, this structure would have been obscured. If functionbodies are included in the declaration of a realistically sized namespace, you typically have to wadethrough screenfuls of information to find what services are offered, that is, to find the interface.An alternative to relying on separately specified interfaces is to provide a tool that extracts aninterface from a module that includes implementation details. I don’t consider that a good solution.Specifying interfaces is a fundamental design activity, a module can provide different interfaces todifferent users, and often an interface is designed long before the implementation details are madeconcrete.Here is a version of the Parser with the interface separated from the implementation:namespace Parser {double prim(bool);double term(bool);double expr(bool);}double Parser::prim(bool get) { /* ...

*/ }double Parser::term(bool get) { /* ... */ }double Parser::expr(bool get) { /* ... */ }Note that as a result of separating the implementation from the interface, each function now hasexactly one declaration and one definition. Users will see only the interface containing declarations. The implementation – in this case, the function bodies – will be placed ‘‘somewhere else’’where a user need not look.Ideally, every entity in a program belongs to some recognizable logical unit (‘‘module’’).Therefore, every declaration in a nontrivial program should ideally be in some namespace named toindicate its logical role in the program. The exception is main(), which must be global in order forthe compiler to recognize it as special (§2.2.1, §15.4).402NamespacesChapter 1414.3.2 ImplementationsWhat will the code look like once it has been modularized? That depends on how we decide toaccess code in other namespaces.

Характеристики

Тип файла
PDF-файл
Размер
18,76 Mb
Тип материала
Высшее учебное заведение

Список файлов книги

Свежие статьи
Популярно сейчас
А знаете ли Вы, что из года в год задания практически не меняются? Математика, преподаваемая в учебных заведениях, никак не менялась минимум 30 лет. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6417
Авторов
на СтудИзбе
307
Средний доход
с одного платного файла
Обучение Подробнее