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.
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 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;
};
}
With one of my projects I will head into the C++ field. Basically I am coming
from a Java background and was wondering how the concept of Java packages
is realized in the C++ world. This led me to the C++ concept of namespaces.
I am absolutely fine with namespaces so far but when it comes to header files
things are becoming kind of inefficient with respect to fully qualified class
names, using-directives and using-declarations.
A very good description of the issue is this article by Herb Sutter.
As I understand it this all boils down to: If you write a header file always
use fully qualified type names to refer to types from other namespaces.
This is almost unacceptable. As a C++ header commonly provides the declaration
of a class, a maximum of readability has top priority. Fully qualifying each
type from a different namespace creates a lot of visual noise, finally
diminishing readability of the header to a degree which raises the question
whether to use namespaces at all.
Nevertheless I want to take advantage of C++ namespaces and so put some thought into
the question: How to overcome the namespace evil of C++ header files? After
some research I think typedefs could be a valid cure to this problem.
Following you will find a C++ sample program which demonstrates how I would
like to use public class scoped typedefs to import types from other namespaces.
The program is syntactically correct and compiles fine on MinGW W64. So far so
good, but I am not sure whether this approach happily removes the using keyword
from the header but brings in another problem which I am simply not aware of.
Just something tricky like the things described by Herb Sutter.
That is I kindly ask everybody who has a thorough understanding of C++ to
review the code below and let me know whether this should work or not. Thanks
for your thoughts.
MyFirstClass.hpp
#ifndef MYFIRSTCLASS_HPP_
#define MYFIRSTCLASS_HPP_
namespace com {
namespace company {
namespace package1 {
class MyFirstClass
{
public:
MyFirstClass();
~MyFirstClass();
private:
};
} // namespace package1
} // namespace company
} // namespace com
#endif /* MYFIRSTCLASS_HPP_ */
MyFirstClass.cpp
#include "MyFirstClass.hpp"
using com::company::package1::MyFirstClass;
MyFirstClass::MyFirstClass()
{
}
MyFirstClass::~MyFirstClass()
{
}
MySecondClass.hpp
#ifndef MYSECONDCLASS_HPP_
#define MYSECONDCLASS_HPP_
#include <string>
#include "MyFirstClass.hpp"
namespace com {
namespace company {
namespace package2 {
/*
* Do not write using-declarations in header files according to
* Herb Sutter's Namespace Rule #2.
*
* using std::string; // bad
* using com::company::package1::MyFirstClass; // bad
*/
class MySecondClass{
public:
/*
* Public class-scoped typedefs instead of using-declarations in
* namespace package2. Consequently we can avoid fully qualified
* type names in the remainder of the class declaration. This
* yields maximum readability and shows cleanly the types imported
* from other namespaces.
*/
typedef std::string String;
typedef com::company::package1::MyFirstClass MyFirstClass;
MySecondClass();
~MySecondClass();
String getText() const; // no std::string required
void setText(String as_text); // no std::string required
void setMyFirstInstance(MyFirstClass anv_instance); // no com::company:: ...
MyFirstClass getMyFirstInstance() const; // no com::company:: ...
private:
String is_text; // no std::string required
MyFirstClass inv_myFirstInstance; // no com::company:: ...
};
} // namespace package2
} // namespace company
} // namespace com
#endif /* MYSECONDCLASS_HPP_ */
MySecondClass.cpp
#include "MySecondClass.hpp"
/*
* According to Herb Sutter's "A Good Long-Term Solution" it is fine
* to write using declarations in a translation unit, as long as they
* appear after all #includes.
*/
using com::company::package2::MySecondClass; // OK because in cpp file and
// no more #includes following
MySecondClass::MySecondClass()
{
}
MySecondClass::~MySecondClass()
{
}
/*
* As we have already imported all types through the class scoped typedefs
* in our header file, we are now able to simply reuse the typedef types
* in the translation unit as well. This pattern shortens all type names
* down to a maximum of "ClassName::TypedefTypeName" in the translation unit -
* e.g. below we can simply write "MySecondClass::String". At the same time the
* class declaration in the header file now governs all type imports from other
* namespaces which again enforces the DRY - Don't Repeat Yourself - principle.
*/
// Simply reuse typedefs from MySecondClass
MySecondClass::String MySecondClass::getText() const
{
return this->is_text;
}
// Simply reuse typedefs from MySecondClass
void MySecondClass::setText(String as_text)
{
this->is_text = as_text;
}
// Simply reuse typedefs from MySecondClass
void MySecondClass::setMyFirstInstance(MyFirstClass anv_instance)
{
this->inv_myFirstInstance = anv_instance;
}
// Simply reuse typedefs from MySecondClass
MySecondClass::MyFirstClass MySecondClass::getMyFirstInstance() const
{
return this->inv_myFirstInstance;
}
Main.cpp
#include <cstdio>
#include "MySecondClass.hpp"
using com::company::package2::MySecondClass; // OK because in cpp file and
// no more #includes following
int main()
{
// Again MySecondClass provides all types which are imported from
// other namespaces and are part of its interface through public
// class scoped typedefs
MySecondClass *lpnv_mySecCls = new MySecondClass();
// Again simply reuse typedefs from MySecondClass
MySecondClass::String ls_text = "Hello World!";
MySecondClass::MyFirstClass *lpnv_myFirClsf =
new MySecondClass::MyFirstClass();
lpnv_mySecCls->setMyFirstInstance(*lpnv_myFirClsf);
lpnv_mySecCls->setText(ls_text);
printf("Greetings: %s\n", lpnv_mySecCls->getText().c_str());
lpnv_mySecCls->setText("Goodbye World!");
printf("Greetings: %s\n", lpnv_mySecCls->getText().c_str());
getchar();
delete lpnv_myFirClsf;
delete lpnv_mySecCls;
return 0;
}
Pain is mitigated by reducing complexity. You're bending C++ into Java. (That works just as bad as trying the other way.)
Some hints:
Remove the "com" namespace level. (This is just a java-ism that you don't need)
Drop the "company" namespace, maybe replace by "product" or "library" namespace (i.e. boost, Qt, OSG, etc). Just pick something that's unique w.r.t. the other libs you're using.
You don't need to fully declare names that are in the same namespace you're in (caveat emptor: template classe, see comment). Just avoid any using namespace directives in the headers. (And use with care in C++ files, if at all. Inside functions is preferred.)
Consider namespace aliases (in functions/cpp files), i.e namespace bll = boost::lambda;. This creates shortcuts that are quite neat.
Also, by hiding private members/types using the pimpl pattern, your header have less types to expose.
P.S: Thanks to #KillianDS a few good tips in comments (that were deleted when I edited them into the question.)
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>
}
}
Could somebody tell me what is the difference between
using namespace android;
....
and
namespace android {
....
}
I found that almost all .cpp files in Android source code use the second one.
Also, If I want to include some files that use the type of second one in my own project, do I need to use namespace android{...} too?
Because if I do not, compiler would report error when I call methods of included files. Or do I need to add any prefix before method call?
namespace android {
extern int i; // declare here but define somewhere
void foo ();
}
-- is used for scoping variables and functions inside a particular name. While using/calling those variables/functions, use scope resolution operator ::. e.g.
int main ()
{
android::foo();
}
There is no restriction for putting all namespace declarations in a single body instance. Multiple namespace android bodies spread across several files, is possible and also recommended sometimes. e.g.
// x.cpp
namespace android {
void somefunc_1 ();
}
// y.cpp
namespace android {
void somefunc_2 ();
}
Now, sometimes you may find using :: operator inconvenient if used frequently, which makes the names unnecessarily longer. At that time using namespace directive can be used.
This using directive can be used in function scope / namespace scope / global scope; But not allowed in class scope: Why "using namespace X;" is not allowed inside class/struct level?).
int main ()
{
using namespace android;
foo(); // ok
}
void bar ()
{
foo(); // error! 'foo' is not visible; must access as 'android::foo()'
}
BTW, Had using namespace android; declared globally (i.e. above main()), then foo() can be accessed without :: in Bar() also.
My answer is probably only helpful if you are more experienced with Java. I'm guessing since you are doing android stuff that this is the case.
The following means that you are declaring a class called MyClass in the namespace android. The qualified name of the class would be android::MyClass.
namespace android {
class MyClass {...};
}
It can be thought of similarly to the Java code:
package android;
public class MyClass {...}
The following means that you can use classes, functions etc. defined in the android namespace without having to use their qualified name (assuming they have been included).
using namespace android;
This
#include <path/to/MyClass.h>
using namespace android;
can be thought of similarly to the Java code:
import android.MyClass;