I'm structuring a c++ game, which works with an engine library that applies all the necessary rendering and the such to the game. I want to separate the namespace into multiple files, so I've created my entity class into two separate files and did this to include it in the namespace:
namespace engine {
void init();
void end();
#include "entity/entitiy.hpp" // <- holds the entity class (pretty much copies it over)
};
This compiles and works perfectly fine. For some reason this feels like some sort of cheat, (probably because includes are usually put at the beginning of a c++ program) and I'm wondering if there's a better way to achieve this.
I want to separate the namespace into multiple files
I'm wondering if there's a better way to achieve this.
Multiple namespace declarations of same name are simply declarations of the same namespace. There is no need to use your trick to define a class inside a namespace.
You can achieve defining the entity class within the engine namespace, while separating the namespace into multiple files like this:
// entity/entitiy.hpp
namespace engine {
class entity { /**/ };
};
// another/header.hpp
namespace engine {
void init();
void end();
};
namespace engine {
void init();
void end();
#include "entity/entitiy.hpp" // <- holds the entity class (pretty much copies it over)
};
This compiles and works perfectly fine.
This is a bad idea. If "entity/entitiy.hpp" is intended to be included by the user of the library, they'll end up defining the class outside of the engine namespace, thus defining a separate class.
Furthermore, if you include anything within "entity/entitiy.hpp", then those includes end up within engine namespace which in many cases is undesirable.
Related
I am designing a SDK written in C++.
I have a question: could or should I totally hide the internal class in my public C++ header file?
The code snippets are like the following (in the header file MyPublicClass.h):
namespace PublicNamespace
{
namespace InternalNamespace
{
class MyInternalClass;
}
class MyPublicClass
{
public:
void SomeMemberFunc();
...
private:
std::shared_ptr<InternalNamespace::MyInternalClass> mImpl;
}
}
Per the C++ PImpl design pattern (and also many other materials from Google), it is OK to put the InternalNamespace::MyInternalClass into the public header.
My thought is: it looks unnecessary to let the external users know the internal namespace InternalNamespace, and also the class MyInternalClass. So I want to use void to replace the type InternalNamespace::MyInternalClass.
That's to say, for my case, I use std::shared_ptr<void> as the type of the data member mImpl, and in the .cpp file, use std::static_pointer_cast<InternalNamespace::MyInternalClass>(mImpl) to convert it to the actual class.
(Yeah, I know there is a little cost with this conversion but please ignore it).
Is this design correct or proper? Thanks all.
Don't use void or void * unless there is absolutely no alternative -- using void-pointers prevents the compiler from catching mistakes at compile-time, and leads to pain and suffering.
Using a clearly-labelled InternalNamespace should be good enough (assuming the programmers using your API aren't deliberately looking for trouble -- and if they are, there are plenty of other ways for them to find it anyway), although if you wanted to hide MyInternalClass entirely from calling code, you could instead make it an inner-class of MyPublicClass, i.e. something like this:
namespace PublicNamespace
{
class MyPublicClass
{
public:
void SomeMemberFunc();
...
private:
class MyInternalClass
{
[...]
};
std::shared_ptr<MyInternalClass> mImpl;
}
}
Since it's declared in the private section of MyPublicClass, no calling code outside of MyPublicClass would be able to access it at all.
I wish to know the actual reason behind writing the class names inside namespace. What purpose do they solve? Do they include the classes or do something else? Any help is greatly appreciated.
namespace ns3 {
class Channel;
class SpectrumChannel;
class MyMod; ;
class NewModule : public NetDevice
{
public:
// methods and data
}
It is good practice to put your classes into a namespace in order to avoid a name collision with other code (libraries) you might use (also coming in later in a project). When using common names like Vector, Logger, etc. as class names it can easily happen that they are also used in other code you want to use. When you put your classes into a (well considered) namespace, this chance of a name-collision is minimized.
Forward declarations are a different (independent) topic. When classes are defined within a namespace, also their forward declarations must be done within that namespace.
I need to add a few methods to c++'s class.
I'm creating a new class using inheritance called "Super_list" that will inherit all of list's methods and allow my to add my own.
#ifndef SUPER_LIST_H
#define SUPER_LIST_H
#include "my_containter.h"
#include <list>
using namespace std;
class My_Container;
class Super_list: public list<My_Container>
{
public:
void new_func1();
void new_func2();
void new_func_3();
};
#endif
This is where I'm using my newly made class:
#ifndef my_container_H
#define my_container_H
#include <list>
#include "super_list.h"
using namespace std;
class Super_list;
class My_container
{
private:
Super_list buddy;
};
#endif
I'm getting a bunch of error relating to the inheritance not being done correctly.
I would appreciate any help or other ideas from completing this task.
Thanks :)
You have a cyclic dependency: MyContainer needs so know about Super_list and vice versa. You need to find a way to break this dependency. Note that in your code, the forward declarations are completely superfluous.
Note also that standard library containers aren't designed to be inherited from publicly.
Concerning the dependency, you need to modify at least one of your classes such that it does not need the full definition of the other. Pretending for a moment that publicly inheriting from std::list is OK, then the only option would be for My_Container not to need the full definition of SuperList by having it hold a (preferably smart) pointer:
class My_container
{
private:
Super_list* buddy;
};
This would allow you to remove the super_list.h include.
One unrelated warning: it is not good to put using namespace std in header files, since it will impose that using directive on all code that, directly or indirectly, includes your header. This can lead to all kind of trouble. I usually go farther and say you shouldn't use it anywhere. Not everyone agrees with me on that one.
I would ask if you really do need to inherit to gain additional functionality. Try using a list as a member of your class. Not only will it make your class easier to change, but it means that code that uses your class won't care about whether its a list or not.
Here is more information
Can't say much without the error messeages.
1) You probably want to define some constructors in Super_list which forward their arguments to the std::list constructors.
2) Every time I tried to do something like this (or worked with something like this) it turned out to be a BAD idea. To keep incapsulation, what you probably want is some global functions:
template<class T>
new_func1(std::list<T> &l)
template<class T>
new_func2(std::list<T> &l)
etc.
I am new to C++ but as I understand it is bad to use the using namespace keywords in header files. I am trying to write a template class, and have read that the definition of the template class member functions must be in the header as well as all the template code must be in the same place. My issue is, it can get tedious writing all of the code without the using namespace keywords. For example at the moment I have:
#ifndef RANDOMTREE_H_
#define RANDOMTREE_H_
template<class T>
class RandomTree {
private:
typedef double (*funcion_ptr) (T, T);
public:
RandomTree(std::vector<T> data, std::vector<funcion_ptr>){
...
}
void train_tree();
};
#endif /* RANDOMTREE_H_ */
But I intend to use some boost methods etc inside the function bodies and would like to know if there is a way to not have to keep typing the prefixes std:: and boost::
Well, this code looks pretty good to me.
It's not a big deal to write them once in the declarations.
In the definitions, if you want to omit writing ns::, you may have using namespace ns; inside a function.
Or, just include some names, like: using ns::name;. But I wouldn't do that.
You can also use typedef:
typedef std::string string;
It has the advantage not using using
The options to not having to type the qualifications (std::, boost::) is having using directives. If there was any other way (there isn't in this case), it would carry around the same problem as having the using directives, so either alternative would be equally bad.
Note that using doesn't have to be applied to a namespace. You can, for example, do:
using std::string;
and then directly use string, but this also isn't recommended.
I am writing a C++ header in which I define a
class A {
// ...
};
that I would like to hide from the outside world (because it may change or even be removed in future versions of this header).
There is also a class B in the same header that has an object of class A as a member:
class B {
public:
// ...
private:
A a_;
};
What is a proper way of hiding class A from the outside world?
If I put the definition of A in an unnamed namespace, the compiler issues a warning, so I assume that, due to issues with internal linkage, I should do something else.
The right way to go about it in C++ is PIMPL idiom. Alternative solution is to put the class you want to hide into a nested namespace, which is usually called detail. But that will not make it totally private as users will still be exposed to its dependencies, and will be able to use it directly.
You could do an inner class:
class B
{
class A { /* ... */ };
A a_;
}
Document that this class is not part of the public API and should not be used.
In C++ you have to trusted programs that link with your library code because you have little other choice. C++ has limited "access control" features many of which can be bypassed or abused so you're better of treating your API clients with respect and building trust.
If you design your API to be easy to use correctly and hard to use unintentionally incorrectly then you will be helping your clients and it is hardly your fault if your clients abuse your interface.
An unnamed namespace is useless anyways, as it only protects agains multiple definitions. What you could do is either using the pImpl Idiom, as mentioned in other answers, or use a detail namespace. Works fine for Boost:
namespace detail{
class A{
// ...
};
}
class B{
public:
// ...
private
A a_;
};
Anyone messing with stuff in a detail namespace is asking for trouble. Or maybe obscure it even more
namespace _b_impl_detail{
// ...
};
Anyone who now touches anything inside should be shot in the foot. :)
Instead of class B holding an A object, have it hold an A* instead (or a shared_ptr<A>, or an unique_ptr<A>, etc.). This way class B only needs a forward declaration of class A and class A can be fully defined inside of class B's source file.
If A is an implementation detail of B, don't put its definition in the header at all. Instead:
class B {
...
class A * myA;
};
and then put the definition of A in the B implementation (i.e. .cpp) file.
I'd like to add a small increment over https://stackoverflow.com/a/5780976/1525238 that helped me better solve my peculiar use case, namely where the "main" class is a template and the "helper/inner" class also has to be a template1.
I used a nested namespace called detail, made all "helper" content private and made the "main" class a friend of the "helper" class:
template<__MAIN_TEMPLATE_PARAMS__> class Main;
namespace detail {
template<__HELPER_TEMPLATE_PARAMS__> class Helper {
/* All Main templates are friends */
template<__MAIN_TEMPLATE_PARAMS__> friend class Main;
/* Private stuff, not reachable from the outside */
static void privateThing(){
...
}
};
}
template<__MAIN_TEMPLATE_PARAMS__> class Main {
void usePrivateThing(){
detail::Helper<__DESIRED_HELPER_TEMPLATE_PARAMS__>::privateThing();
}
};
The private stuff is static above only to make the code shorter. They may very well be tied to the Helper instance.
In retrospect, there could certainly be more elegant solutions involving less black magic, but it highly depends on the specific application. I still find the above a legit, nice use case for a friend class.
1 This is because I needed to use a template helper function that required a partial specialization, which is not allowed yet in c++, for no particular reason but is technically possible with a wrapper class. Partial specialization is omitted from the above for simplicity.