1

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 :)

Community
  • 1
  • 1
  • 1
    Sorry, *why* can't you use the namespace? If you can use a class with static methods only, you can use a namespace. – juanchopanza Jul 09 '13 at 19:23
  • My understanding was that a namespace can only be "seen" by classes that are connected in some way. Please correct me if I'm wrong, but if this is the case then my main class wouldn't be able to see the namespace in my player class, for example :) – Bradley Hodgkins Jul 09 '13 at 19:26
  • That understanding sounds wrong. For example, I can create a container class of my own, and use it with standard library algorithms that are in the `std` namespace. – juanchopanza Jul 09 '13 at 19:35
  • So, I have Main, Entity and Player so far, Player has Entity as a base and Main will only ever have objects of Player in it. Could I create a namespace in entity (I plan to make more entities) and use that in Main? :) Thank you, by the way, for helping! – Bradley Hodgkins Jul 09 '13 at 19:39
  • 1
    You can't create namespaces in classes. You can put classes, functions and objects inside of namespaces. – juanchopanza Jul 09 '13 at 19:40
  • Yes I know that, sorry, I meant create the namespace in the Entity file :) I don't want all my classes in the same file, that'd make compilation times run rampant, so if I make the namespace at the top of the class file (outside of the class declaration) could I use that in main and in player easily? :) – Bradley Hodgkins Jul 09 '13 at 19:43

2 Answers2

1

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.
greatwolf
  • 20,287
  • 13
  • 71
  • 105
  • Sigh, this is practically what I posted just after you did. I'll keep mine for reference and another example, but, OP keep in mind @greatwolf was first. – MadDogMcNamara Jul 09 '13 at 22:46
  • 1
    Very helpful thank you :) I'll try implementing this later. you've both been of great help, Thank you :) – Bradley Hodgkins Jul 10 '13 at 05:37
1

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.

MadDogMcNamara
  • 312
  • 1
  • 9
  • Both are great answers, thank you, I gave greatwolf the answer though because his response slightly covered what I think my problem was, yours is great for understanding more about namespaces though, thank you again :) – Bradley Hodgkins Jul 10 '13 at 05:36