I am familiar with the following use of namespaces.
In the header file (for example people.h) I describe interface of a name space. For example:
namespace people{
int getAge(str Name);
void setName(str Name);
}
Then in people.cpp I define the methods from the space name:
#include "people.h"
int people::getAge(str Name) {
something_1;
something_2;
}
void people::setName(str Name) {
something_1;
}
However, in a header file that I have I see that in addition to the namespace people there are also interfaces of other namespaces (for example namespace dogs). And these name spaces are not defined in the people.cpp file.
So, I assumed that (because of some strange reason) the interface for the namespace dogs is put into the people.h and then then the name space dog is defined in the "dogs.cpp" file. So, in other words I assumed that two different name spaces are defined in two different cpp files but their interface is described in one header file. However, this assumption seems to be wrong because I found that there are many header files that declare "namespace dogs".
So, I assume that namespace dogs in the 2people.h" file has another function but I cannot figure out what function it is. Could anybody please help me with that?
ADDED
The code that I try to understand is written not by me and it works fine. So, it should make sense. May be I was not clear enough. So, I try to give an example:
In the header file (people.h) I have:
namespace etet
{
class date;
}
namespace xsystem{
class estimation_module;
}
namespace people {
a_lot_of_different_stuff;
}
Then the people.cpp defines all the methods that belong to the people name space.
The "namespace interface" is a misleading concept. A namespace is just a bounch of names grouped together under a surname (like you and your brothers and sisters). It has no "interface" because there is no namespace "obejct".
The
#include "people.h"
int people::getAge(str Name) {
something_1;
something_2;
}
void people::setName(str Name) {
something_1;
}
is perfectly equivalent to
#include "people.h"
namespace people
{
int getAge(str Name) {
something_1;
something_2;
}
void setName(str Name) {
something_1;
}
}
may be this is more familiar, or may be not.
The fact an header declares functions not present in a cpp, just means they are probably present in another one.
About the fact that the namespace name { ..... } declaration can be repeated in many files, each containing various function is perfectly normal, since the namespace keyword does not declare an object. It just group names. And -in fact- sayning a namespace is "declared" is a common language abuse. What is declared is the name of the namespace.
And different names declare in different places can belong to a same group. there is nothing mysterious in that.
You lexicon makes me thinking you are confusing namespaces with classes and structs
ADDED:
After your clarification, it looks like the a_lot_of_different_stuff contains declarations that use etet::date and xsystem::estimation_module;
This names (and only the names) must be known to the compiler, but the header cannot recursively include ther respective headers because they most likely already included people.h.
A typical "curculare reference" problem, like in here, but involving different namespaces.
You're confusing namespaces and classes. Typically, a class definition occurs in a header file (.h) and the implementation of its member functions appear in the corresponding implementation file (.cpp).
A namespace works differently to a class. If a class is defined in multiple translation units, it must have precisely the same tokens in all of them. You can't even reorder members, even if it would result in the exact same class. It's easy to meet this requirement by using the above described header files. Each translation unit that needs a class foo contains the contents of foo.h because they do #include "foo.h" when they need it. Of course they all contain precisely the same definition of foo bceause they all included foo.h.
However, this is very different to namespaces. A namespace can be introduced multiple times across the same and different translation units without it being the same tokens every time. Something like this is totally fine:
namespace bar {
void baz();
struct x;
}
// some stuff
namespace bar {
void do_something(x);
}
Each occurence of namespace bar introduces some declarations to that namespace.
You will often have many classes defined in the same namespace. Each header for those classes will do namespace whatever { ... } and introduce the class definition into that namespace.
Sometimes you will even want to introduce things to multiple namespaces or nested namespaces in a single header file. There's nothing to stop you doing that. A possible situation for doing that is if you want to forward declare something from another namespace. Let's say you have a class defined in people.h like so:
namespace people {
class person {
dogs::dog* pet_dog;
};
}
Now, this class needs to know about the type dog in the dogs namespace. One way to do his would be to #include "dogs.h". However, since pet_dog is only a pointer, we can do with an incomplete type, so we can forward declare dog like so:
namespace dogs {
class dog;
}
namespace people {
class person {
dogs::dog* pet_dog;
};
}
Related
Most classes appear to be separated between declaration and definition in the following form using namespace qualifier to define the class:
// test.h
class test
{
public:
void func1(void);
private:
void func2(void);
};
// test.cpp
void test::func1(void)
{
//whatever
}
void test::func2(void)
{
//whatever
}
Why don't we typically see people use the keyword class in the .cpp file? Like in the following form:
// test.cpp
class test {
void func1(void)
{
//whatever
}
void func2(void)
{
//whatever
}
};
Is it just convention to use the namespace qualifiers? Or because it make more sense when you starting implementing a class via multiple source files?
Let's view this question from another angle...
It is possible to use the same syntax for both, but it's "the other one"; the following is perfectly valid:
namespace ns
{
int foo();
}
int ns::foo() { return 0; }
Looked at like this, it's the opposite question that's interesting, "why is it common to include the word 'namespace' in .cpp files?"
There's one substantial difference between namespaces and classes that makes namespace {} necessary in so many places: namespaces are open to extension, but classes are defined entirely by their (one and only) definition.
Like with classes, you can't add anything to a namespace using the syntax above; you can't add a function bar above with only int ns::bar() { return 9; }, the only way to add names to a namespace is "from within".
And, as many have discovered, it's convenient to wrap an entire file in a namespace and not use the qualified names, even if you're not adding any names to it.
Hence the popularity of "namespace": it's a convenience enabled by the extensibility of namespaces.
Another issue is that the meaning of your "test.cpp" would depend on whether the class definition has already been seen by the compiler – without it, that's a valid and complete definition of a class with two private functions.
This kind of "action from a distance" depending on possibly very distant code is painful to work with.
It's also worth noting that namespaces were added some twenty years after "C with classes" was created, when C++ was a well established language, and changing the meaning of a construct that literally hasn't changed in decades is pretty much unthinkable.
Partularly if all it does is save a few keystrokes.
I'm a newbie in c++.
Why, in Eclipse (configured with MinGW) and also in other threads, I noticed is used to add a class to a namespace?
I provide an example to show you my actual doubt:
#ifndef MODEL_MANGO_HPP_
#define MODEL_MANGO_HPP_
namespace std {
class Mango {
public:
Mango();
virtual ~Mango();
};
} /* namespace std */
#endif /* MODEL_MANGO_HPP_ */
EDIT: As shown in comments, it's completely forbidden to add classes to namespace std. Quoting #owacoder,
Namespaces are never closed, so you always have the ability to add
class definitions to them. However, by the specification the std
namespace is to be considered closed.
To provide you a complete view of the context, here is the default implementation of the Mango.cpp, that Eclipse has done for me:
#include "Mango.hpp"
namespace std {
Mango::Mango() {
// TODO Auto-generated constructor stub
}
Mango::~Mango() {
// TODO Auto-generated destructor stub
}
} /* namespace std */
So my question changes into:
Why it's used "namespace std {...}" and when is a good practice to add classes to a namespace?
You have to understand the basics of what classes and namespaces are.
classes (along with structs, enums, and enum classes) are used to define user defined types in C++.
You create a class to represent a logical entity and encapsulate details, etc.
namespaces are a way to mark territories of code and qualifying unique names for variables.
if you just write a class in a file, it will be written in the "global namespace" and it is not considered good practice because you are "polluting the namespace".
instead, you should use namespaces to limit the scope where your variable names have meaning. this way, you are not exhausting the pool of sensible class and variable names quickly (how many times have you wanted to write a "Utility" class?)
namespace firstNamespace{
int x=2;
}
namespace secondNamespace{
int x=7;
}
int main ()
{
std::cout << firstNamespace::x << '\n';
std::cout << secondNamespace::x << '\n';
return 0;
}
in this case, you can see that we can "reuse" the variable name x in different Contexts by qualifying a namespace. inside the namespace blocks, we could have more declarations and definitions. including functions, classes, structs, etc.
take not that namespaces remain open and you can add to them later.
for example you can have this:
namespace firstNamespace{
int x=2;
}
namespace secondNamespace{
int x=7;
}
namespace firstNamespace{
int y=11;
}
here, we added firstNamespace::y.
More importantly, you can observe that std is a namespace provided by C++ that contains a lot of useful variables, objects like cout which is of type std::ostream, functions and classeslike std::vector, std::ostream, etc.
so to go back to your question, the reason you want to wrap your class definitions in namespaces is to not pollute the global namespace.
Let's say the Acme company releases a useful library with an extremely ugly C API. I'd like to wrap the structs and related functions in C++ classes. It seems like I can't use the same names for the wrapper classes, because the original library is not inside a namespace.
Something like this is not possible, right?
namespace AcmesUglyStuff {
#include <acme_stuff.h> // declares a struct Thing
}
class Thing {
public:
...
private:
AcmesUglyStuff::Thing thing;
};
Linking will be a problem.
The only way I can think to wrap the library, and not pollute my namespace with the C library names, is a hack like this, reserving space in the class:
// In mything.h
namespace wrapper {
class Thing {
public:
...
private:
char impl[SIZE_OF_THING_IN_C_LIB];
};
}
// In thing.cc
#include <acme_stuff.h>
wrapper::Thing::Thing() {
c_lib_function((::Thing*)impl); // Thing here referring to the one in the C lib
}
Is that the only way? I'd like to avoid putting prefixes on all my class names, like XYThing, etc.
Seems like you're making this harder than it needs to be.
#include "acme_stuff.h" // puts all of its names in global namespace
namespace acme {
class Thing {
public:
// whatever
private:
::Thing thing;
};
}
Now just use acme::Thing rather than Thing.
If it's really important to you to not have the C names in the global namespace, then you need a level of indirection:
namespace acme {
class Thing {
public:
Thing();
~Thing();
// whatever
private:
void *acme_thing;
};
}
In your implementation file, #include "acme_stuff.h", in your constructor create a new ::Thing object and store its address in acme_thing, in your destructor delete it, and in your member functions cast acme_thing to type ::Thing*.
It's not a good idea to try to name something the exact same thing as something else. (I mean equal fully-qualified names, including all namespaces.) If some library has already grabbed the obvious best name in the global namespace, you'll need to pick a different name.
You could put your class Thing in a namespace as Pete Becker suggests, and then use ::Thing to access Acme's Thing. That would be fine if you're prepared to always access your class through it's fully namespace-qualified name (e.g. My::Thing). It's tempting to try using My::Thing; or using namespace My;, but that won't work, because any translation unit that includes the definition of your class (e.g. via a header file you create) must necessarily pull Acme's Thing into the global namespace first (otherwise an "Undefined symbol" compilation error would occur when parsing the definition of My::Thing).
Is it really a C API? Try to extern "C" {} to whole included header to solve the linking problem.
namespace AcmesUglyStuff {
extern "C" {
#include <acme_stuff.h>
}
}
This question already has answers here:
Is it possible to avoid repeating the class name in the implementation file?
(8 answers)
Closed 6 years ago.
If in C++ I have a class longUnderstandableName. For that class I have a header file containing its method declaration. In the source file for the class, I have to write longUnderstandableName::MethodA, longUnderstandableName::MethodB and so on, everywhere.
Can I somehow make use of namespaces or something else so I can just write MethodA and MethodB, in the class source file, and only there?
typedef longUnderstandableName sn;
Then you can define the methods as
void sn::MethodA() {}
void sn::MethodB() {}
and use them as
sn::MethodA();
sn::MethodB();
This only works if longUnderstandableName is the name of a class. It works even if the class is deeply embedded in some other namespace.
If longUnderstandableName is the name of a namespace, then in the namespace (or source file) where you want to use the methods, you can write
using namespace longUnderstandableName;
and then call methods like
MethodA();
MethodB();
You should be careful not to use a using namespace foo; in header files, because then it pollutes every .cpp file that we #include the header file into, however using a using namespace foo; at the top of a .cpp file is definitely allowed and encouraged.
Inside the methods of the classes, you can use the name without qualification, anyway: just drop the longUnderstandableName:: prefix.
In functions inside the class source file that are not methods, I suggest to introduce file-scope static inline functions, like so:
inline type MethodA(type param){
return longUnderstandableName::MethodA(param);
}
Then you can call MethodA unqualified; due to the inline nature, this likely won't cost any runtime overhead.
I'm not sure I'd recommend it, but you could use a macro like:
#define sn LongUnderstandableName
void sn::MethodA(parameters) { ... }
int sn::MethodB(parameters) { ... }
and so on. One of the bad points of macros is that they don't respect scope, but in this case, the scope you (apparently) want is the source file, which happens to correspond (pretty closely) with the scope of a macro.
Well, yes, once you understand namespaces.
Instead of naming your class MyBonnieLiesOverTheOcean, instead set up the following:
namespace My { namespace Bonnie { namespace LiesOverThe {
class Ocean { ... };
} } }
Now, when defining your methods, you put the same namespaces around the whole file, and you write:
Ocean::SomeMethod() ...
When using the class from outside all the namespaces, it's:
My::Bonnie::LiesOverThe::Ocean
If you need to reference a lot of things from some other namespace in some source file, you can use the 'use' directive to ditch the prefixes.
I want to make a namespace that will contain several classes as part of a "package".
Do I have to declare all of the classes within the namespace?
For example, if I have a "2dEngine.h" which defines the 2dEngine namespace, do I have to declare all of the individual classes within that header file? Or can I still separate them into separate header (.h) files and have them be part of the namespace?
Pseudo example:
TwoEngine.h
namespace TwoEngine
{
class Canvas
{
// Define all of Canvas here
};
class Primitive
{
// Define all of Primitive here
};
}
Instead of doing that, I want to have Canvas and Primitive be their own .h files and just somehow state that they are part of that namespace.
Sorry, I'm still pretty new to this.
Yes, you can split the namespace into multiple blocks (and hence files). Your classes will belong to the same namespace as long as they are declared in the namespace block with the same name.
// Canvas.h
namespace TwoEngine
{
class Canvas
{
// Define all of Canvas here
};
}
// Primitive.h
namespace TwoEngine
{
class Primitive
{
// Define all of Primitive here
};
}
Namespaces can be discontiguous. You can take advantage of this by keeping relevant classes in your 2DEngine.h which probably is going to be used by client code and will be shipped as part of your library.
Anything else, that is not to be revealed to the outside world can still be put in the same namespace but in a separate header file (which is not shipped).
Header H1.h (part of the library interface to the external world)
namespace TwoEngine
{
class Canvas
{
// Define all of Canvas here
};
}
Header H2.h (not part of the library interface to the external world)
#include "H1.h"
namespace TwoEngine // reopen the namespace and extend it
{
class Primitive
{
// Define all of Primitive here
};
}
Yes just use the name space directive inside the implementation files also.