What Exactly Is a Namespace and Why Is It Necessary

What exactly is a namespace and why is it necessary

From cppreference.com:

Namespaces provide a method for preventing name conflicts in large
projects.

Symbols declared inside a namespace block are placed in a named scope
that prevents them from being mistaken for identically-named symbols
in other scopes.

Multiple namespace blocks with the same name are allowed. All
declarations within those blocks are declared in the named scope.

A namespace works to avoid names conflicts, for example the standard library defines sort() but that is a really good name for a sorting function, thanks to namespaces you can define your own sort() because it won't be in the same namespace as the standard one.

The using directive tells the compiler to use that namespace in the current scope so you can do

int f(){
std::cout << "out!" << std::endl;
}

or:

int f(){
using namespace std;
cout << "out!" << endl;
}

it's handy when you're using a lot of things from another namespace.

source: Namespaces - cppreference.com

What are namespaces?

Namespacing does for functions and classes what scope does for variables. It allows you to use the same function or class name in different parts of the same program without causing a name collision.

In simple terms, think of a namespace as a person's surname. If there are two people named "John" you can use their surnames to tell them apart.

The Scenario

Suppose you write an application that uses a function named output(). Your output() function takes all of the HTML code on your page and sends it to the user.

Later on your application gets bigger and you want to add new features. You add a library that allows you to generate RSS feeds. This library also uses a function named output() to output the final feed.

When you call output(), how does PHP know whether to use your output() function or the RSS library's output() function? It doesn't. Unless you're using namespaces.

Example

How do we solve having two output() functions? Simple. We stick each output() function in its own namespace.

That would look something like this:

namespace MyProject;

function output() {
# Output HTML page
echo 'HTML!';
}

namespace RSSLibrary;

function output(){
# Output RSS feed
echo 'RSS!';
}

Later when we want to use the different functions, we'd use:

\MyProject\output();
\RSSLibrary\output();

Or we can declare that we're in one of the namespaces and then we can just call that namespace's output():

namespace MyProject;

output(); # Output HTML page
\RSSLibrary\output();

No Namespaces?

If we didn't have namespaces we'd have to (potentially) change a lot of code any time we added a library, or come up with tedious prefixes to make our function names unique. With namespaces, we can avoid the headache of naming collisions when mixing third-party code with our own projects.

What is a Namespace?

A namespace provides a container to hold things like functions, classes and constants as a way to group them together logically and to help avoid conflicts with functions and classes with the same name that have been written by someone else.

In Ruby this is achieved using modules.

What does using namespace do exactly?

The directive using namespace X; makes names from namespace X visible inside the namespace containing the directive. That is, when looking up a name n in that scope, X::n can be found. However, it will only be looked for if the compiler needs to look for it.

In your example, this declaration:

std::string test = "Test";

inside the global namespace makes perfect sense as-is. The name test is simply introduced, as with any other declaration. No need to look it up anywhere.

This would be an entirely different kettle of fish:

namespace X
{
struct C
{
static std::string test;
};
}

using namespace X;
std::string C::test = "Test";

In this code, the compiler needs to know what C is to make sense of the definition of C::test. It therefore does a name lookup of C, which indeed finds X::C thanks to the using directive.

How do you properly use namespaces in C++?

Namespaces are packages essentially. They can be used like this:

namespace MyNamespace
{
class MyClass
{
};
}

Then in code:

MyNamespace::MyClass* pClass = new MyNamespace::MyClass();

Or, if you want to always use a specific namespace, you can do this:

using namespace MyNamespace;

MyClass* pClass = new MyClass();

Edit: Following what bernhardrusch has said, I tend not to use the "using namespace x" syntax at all, I usually explicitly specify the namespace when instantiating my objects (i.e. the first example I showed).

And as you asked below, you can use as many namespaces as you like.

is it necessary for the namespace to be the name of the file in c#?

No, the namespace can be anything, they don't have to be the same as the filename. It is good practice to have the namespaces correspond to physical file paths (folders in your solution).

So if you have a file in .\Interfaces\ViewModels\Client, usually the namespace declaration in that file will be:

namespace DefaultNamespaceOfAssembly.Interfaces.ViewModels.Client { ... }

ReSharper even offers to fix up namespaces that are breaking this rule.

The purpose of the namespace is to

  • modularize your code by putting things that belong together (by functionality for example) in the same namespace,

  • reduce name collisions. Without namespaces importing an external library would result in hell if it were to contain classes with the same name as classes in your own code.

Probably there are more, but at first thought these come to mind, although these two should already be enough to justify their existance.

Need of namespace in XML

In general, an XML namespace does not serve any purpose apart from uniquely identifying the elements that are associated with it.

In other words, the String "http://www.myNameSpace.com" as in:

<rootElement xmlns:myNameSpace="http://www.myNameSpace.com">

is purely arbitrary. It does not have to point anywhere. Also, the so-called prefix (in this case myNameSpace, the part right after "xmlns:") is arbitrary and just a shorthand way of saying "http://www.myNameSpace.com".

Having said that, a few reservations:

1) Namespaces can help structure your XML data in large files, for example a Microsoft Word document in OpenXML format:

This is an excerpt of the namespaces present in typical OOXML:

xmlns:aml="http://schemas.microsoft.com/aml/2001/core"
xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas"
xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

So, although there is no inherent reason to have separate namespaces, it helps dividing your XML vocabulary into meaningful categories.

2) There are a few constraints on arbitrarily defining namespaces, as you noticed:

xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

This identifies elements as belonging to the XSLT namespace. But also, beyond that, it means that elements thus marked are identified by an XSLT processor as not merely being XML code, but an XSLT instruction to be carried out.

The link "http://www.w3.org/1999/XSL/Transform" points to the XSLT specification, where the rules for transforming XML documents are laid down. Now, to answer your question: Declaring the namespace does not help the transformation. Rather, an XSLT processor does not recognize XSLT code if you omit it.

You can define the namespaces "namespaceA" and "namespaceB":

xmlns:nsA="namespaceA"
xmlns:nsB="namespaceB"

but you cannot use them to transform XML, unless you meant to just change the prefix:

xmlns:nsA="http://www.w3.org/1999/XSL/Transform"

which is considered bad practice.

Why is using namespace std; considered bad practice?

Consider two libraries called Foo and Bar:

using namespace foo;
using namespace bar;

Everything works fine, and you can call Blah() from Foo and Quux() from Bar without problems. But one day you upgrade to a new version of Foo 2.0, which now offers a function called Quux(). Now you've got a conflict: Both Foo 2.0 and Bar import Quux() into your global namespace. This is going to take some effort to fix, especially if the function parameters happen to match.

If you had used foo::Blah() and bar::Quux(), then the introduction of foo::Quux() would have been a non-event.



Related Topics



Leave a reply



Submit