官术网_书友最值得收藏!

  • C++ Fundamentals
  • Antonio Mallia Francesco Zoffoli
  • 830字
  • 2021-06-11 13:36:00

Namespaces

One of the goals of functions is to better organize our code. To do so, it is important to give meaningful names to them.

For example, in package management software, there might be a function called sort for sorting packages. As you can see, the name is the same as the function that would sort a list of numbers.

C++ has a feature that allows you to avoid these kinds of problems and groups names together: namespaces.

A namespace starts a scope in which all the names declared inside are part of the namespace.

To create a namespace, we use the namespace keyword, followed by the identifier and then the code block:

namespace example_namespace {

// code goes here

}

To access an identifier inside a namespace, we prepend the name of the namespace to the name of the function.

Namespaces can be nested as well. Simply use the same declaration as before inside the namespace:

namespace parent {

namespace child {

// code goes here

}

}

To access an identifier inside a namespace, you prepend the name of the identifier with the name of the namespace in which it is declared, followed by ::.

You might have noticed that, before we were using std::cout. This is because the C++ standard library defines the std namespace and we were accessing the variable named cout.

To access an identifier inside multiple namespaces, you can prepend the list of all the namespaces separated by ::parent::child::some_identifier. We can access names in the global scope by prepending :: to the name—::name_in_global_scope.

If we were to only use cout, the compiler would have told us that the name does not exist in the current scope.

This is because the compiler searches only in the current namespace and the parent namespaces to find an identifier by default, so unless we specify the std namespace, the compiler will not search in it.

C++ helps make this more ergonomic with the help of the using declaration.

The using declaration is defined by the using keyword, followed by an identifier specified with its namespaces.

For example, using std::cout; is a using declaration that declares that we want to use cout. When we want to use all the declarations from a namespace, we can write using namespace namespace_name;. For example, if we want to use every name defined in the std namespace, we would write: using namespace std;.

When a name is declared inside the using declaration, the compiler also looks for that name when looking for an identifier.

This means that, in our code, we can use cout and the compiler will find std::cout.

A using declaration is valid as long as we are in the scope in which it is declared.

Note

To better organize your code and avoid naming conflicts, you should always put your code inside a namespace that's specific to either your application or library.

Namespaces can also be used to specify that some code is used only by the current code.

Let's imagine you have a file called a.cpp that contains int default_name = 0; and another file called b.cpp with int default_name = 1;. When you compile the two files and link them together, we get an invalid program: the same variable has been declared with two different values, and this violates the One Definition Rule (ODR).

But you never meant for those to be the same variable. To you, they were some variables that you just wanted to use inside your .cpp file.

To tell that to the compiler, you can use anonymous namespaces: a namespace with no identifier.

All the identifiers created inside it will be private to the current translation unit (normally the .cpp file).

How can you access an identifier inside an anonymous namespace? You can access the identifier directly, without the need to use the namespace name, which does not exist, or the using declaration.

Note

You should only use anonymous namespaces in .cpp files.

Activity 5: Organizing Functions in Namespaces

Write a function to read the name of a car for a lottery in a namespace based on numerical input. If the user inputs 1, they win a Lamborghini, and if the user inputs 2, they win a Porsche:

  1. Define the first namespace as LamborghiniCar with an output() function that will print "Congratulations! You deserve the Lamborghini." when called.
  2. Define the second namespace as PorscheCar with an output() function that will print "Congratulations! You deserve the Porsche." when called.
  3. Write a main function to read the input of numbers 1 and 2 into a variable called magicNumber.
  4. Create an if-else loop with the if condition calling the first namespace with LamborghiniCar::output() if the input is 1. Otherwise, the second namespace is called similarly when the input is 2.
  5. If neither of these conditions are met, we print a message asking them to enter a number between 1 and 2.

    Note

    The solution for this activity can be found on page 285.

主站蜘蛛池模板: 永城市| 禹城市| 巴彦县| 宜良县| 吐鲁番市| 隆子县| 四子王旗| 上杭县| 轮台县| 井陉县| 舞钢市| 桐庐县| 吉首市| 广宁县| 磴口县| 东至县| 保定市| 玉树县| 邵东县| 宝鸡市| 盐源县| 板桥市| 定边县| 赞皇县| 无极县| 成安县| 丹凤县| 团风县| 大埔区| 通海县| 高青县| 博野县| 雅江县| 洪雅县| 普定县| 辽源市| 蒙自县| 通州区| 任丘市| 华池县| 浦东新区|