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

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.

主站蜘蛛池模板: 石家庄市| 县级市| 鄱阳县| 呼玛县| 盐津县| 民和| 文水县| 崇文区| 黑山县| 茂名市| 绥阳县| 红原县| 鹤山市| 全州县| 泗水县| 苏州市| 康平县| 涟水县| 化隆| 曲靖市| 阿荣旗| 新河县| 马边| 麦盖提县| 刚察县| 巴林左旗| 迁西县| 观塘区| 兴文县| 云和县| 衡南县| 谷城县| 顺义区| 泾阳县| 永仁县| 剑河县| 获嘉县| 桐梓县| 高清| 彭泽县| 内黄县|