user2001721
user2001721

Reputation:

Separate class for a namespace advisable?

I have a couple functions that I want to use in many different classes. I have a couple classes that are derived from one base class and so tried to make it so that the base class held the functions and then the child classes could just call them. This seemed to cause linking errors, and so following advice from this question (Advantages of classes with only static methods in C++) I decided to give namespaces a swing, but the only file that is included by every header/file is resource.h, and I don't want to put a namespace for my functions in there as it seems to specialised to mess with.

My question is, how do I make a class that only includes a namespace, or the functions I want to use, so that I can just include this class and use the functions as desired?

Thank you in advance for the help, the answers I've found on the internet only focus on one file, not multiple files like I'm hoping to address :)

Upvotes: 1

Views: 168

Answers (2)

MadDogMcNamara
MadDogMcNamara

Reputation: 302

You can put anything in a namespace, but you can't put namespaces inside things ( that's not a very formal way of saying it but I hope you get what I mean.

Valid

namespace foospace
{
    class foo
    {
    public : 
        foo();

        ~foo();

        void eatFoo();

    };
}

Invalid

namespace foospace
{
    class foo
    {
    public : 
        foo();

        ~foo();

        namespace eatspace
        {  
            void eatFoo();
        }

    };
}

I'm not 100% certain that the second example wouldn't compile, but regardless, you shouldn't do it.

Now, from your comments it sounds like you want something like this :

In the file Entity.h, your entity class definition :

namespace EntitySpace
{
    class Entity
    {
    public : 
        Entity();
        ~Entity();   
    };
}

In the file Player.h

#include "Entity.h"
namespace EntitySpace
{
    class Player : public Entity
    {
    public : 
        Player();
        ~Player();   
    };
}

In the file main.cpp

#include "Player.h"

int main()
{
    EntitySpace::Player p1;
    EntitySpace::Player p2;

}

So you call upon Player in the EntitySpace namespace. Hope this answers what you were asking.

Upvotes: 0

greatwolf
greatwolf

Reputation: 20838

You seem confused about how namespaces are used. Here are some things to keep in mind when working with namespaces:

  • You create a namespace using the syntax namespace identifier { /* stuff */ }. Everything between the { } will be in this namespace.
  • You cannot create a namespace inside a user-defined type or function.
  • A namespace is an open group construct. This means you can add more stuff into this namespace later on in some other piece of code.
  • Namespaces aren't declared unlike some of the other language constructs.
  • If you want certain classes and/or functions inside a namespace scope, enclose it with the namespace syntax in the header of where it's defined. Modules using those classes will see the namespace when the headers get #include'd.

For example, in your Entity.h you might do:

// Entity.h
#pragma once

namespace EntityModule{
class Entity
{
public:
  Entity();
  ~Entity();
  // more Entity stuff
};

struct EntityFactory
{
  static Entity* Create(int entity_id);
};

}

inside your main.cpp you access it like this:

#include "Entity.h"

int main()
{
  EntityModule::Entity *e = EntityModule::EntityFactory::Create(42);
}

If you also want Player to be inside this namespace then just surround that with namespace EntityModule too:

// Player.h
#pragma once
#include "Entity.h"

namespace EntityModule{
class Player : public Entity
{
  // stuff stuff stuff
};
}

This works because of point #3 above.

If for some reason you feel you need to create a namespace inside a class, you can simulate this to an extent using nested classes:

class Entity
{
public:
  struct InnerEntity
  {
    static void inner_stuff();
    static int  more_inner_stuff;
    private:
      InnerEntity();
      InnerEntity(const InnerEntity &);
  };
  // stuff stuff stuff
};

Some important differences and caveats doing it this way though:

  • Everything is qualified with static to indicate there's no specific instance associated.
  • Can be passed as a template parameter.
  • Requires a ; at the end.
  • You can't create a convenient shorthand with abusing namespace Entity::InnerEntity;. But perhaps this is a good thing.
  • Unlike namespaces, class and struct are closed constructs. That means you cannot extend what members it contains once defined. Doing so will cause a multiple definition error.

Upvotes: 0

Related Questions