3

Simple question, how do I shorten a call/name without using defines.

For example, I have a singleton that I have to call that is within a namespace (I cannot use using namespace blabla because it is not allowed) like so:

MyFW::GameRoot::Instance()->DoSomething();

Now I can assign that to a variable, which works somewhat if I am using it multiple times within the same class/function, but using it in many classes/functions it becomes cumbersome. I decided to use #define for it:

#define MyFW::GameRoot::Instance() ROOT //defined in GameRoot.h

ROOT->DoSomething(); //Used where-ever GameRoot.h is included

Much better, and I really like it especially because now wherever I see ROOT (color coded through V-Assist) I know what it is immediately... unless I have a breakpoint there and I need Visual Studio to resolve ROOT to show up in the watch window (or even hover over it to quickly pull up the object in debug), which it cannot do.

Is there any other option? What do you guys do to shorten names? Simply use local/member pointers to store the instance?

Thanks!

Samaursa
  • 16,527
  • 21
  • 89
  • 160

4 Answers4

5

Use local references:

MyFW::GameRoot& ROOT = *MyFW::GameRoot::Instance();

Do not use defines.

akira
  • 6,050
  • 29
  • 37
5

You can't use using namespace ..., but can you use

namespace root=MyFW::GameRoot;

Then you can type

root::Instance()->DoSomething();

Defining a namespace like that is better than a #define. (I.e it can't get munged up somewhere else by mistake. The compiler knows what you are trying to do.)

cape1232
  • 999
  • 6
  • 21
  • +1, this is one of those less used C++ features, also mentioned here: http://stackoverflow.com/questions/75538/hidden-features-of-c/78484#78484 – Naveen Jul 16 '10 at 05:03
  • 1
    While we're in picking mode - how much better is that now: `root::Instance()->f(); root::Instance()::g(); root::Instance()::h();`. – Georg Fritzsche Jul 16 '10 at 05:22
  • 1
    namespace MyFW { class GameRoot { ... } }; at least my compiler tells me "foo.cc:36: error: `GameRoot' is not a namespace-name" – akira Jul 16 '10 at 05:30
  • @Georg I agree it is minimally shorter in this case (though you could use `namespace r=...`. I get lots of use out of this technique because I use code that is often nested in 3 levels of namespace with long names. – cape1232 Jul 16 '10 at 20:19
  • I realize I am replying here after quite some time, but I just tried this on another 'problem' area that I ran into and remembered your solution. `namespace newAlias= SomeNameSpace::ClassName;` does not work because a namespace alias can only be given to an existing namespace and not a symbol. So in this question's case, I can only give an alias to `MyFW` which is already short enough to not really require an alias. If the above is wrong, I would grateful for corrections/clarification. Thanks. – Samaursa Oct 14 '10 at 03:33
2

If you want to ease access across multiple functions, just use a helper function:

namespace {
    MyFW::GameRoot* root() { return MyFW::GameRoot::Instance(); }
}

// ...
root()->DoSomething();

Two characters more, but it with comes type-safety included.

Georg Fritzsche
  • 97,545
  • 26
  • 194
  • 236
  • This unnecessarily adds function call cost at runtime. – cape1232 Jul 16 '10 at 05:06
  • 4
    @cape: No it won't unless you are using an antique compiler. The definition is visible and any compiler worth its grain will produce the same results. Check your facts first before downvoting. – Georg Fritzsche Jul 16 '10 at 05:07
  • Touche on that. Separate objection is that it hides the use of Instance(), though. When you're debugging, you say, "Hey, what's root again, where'd it come from?" – cape1232 Jul 16 '10 at 05:11
  • @cape: Thats what the source code is for - use *"jump to definition"* or however your IDE calls it. Whenever you make something more concise you hide information to some degree, so ... I could object to your answer on the same grounds - where is that namespace coming from? – Georg Fritzsche Jul 16 '10 at 05:19
  • exactly. compilers throw such helpers away. the same for references, see my answer. – akira Jul 16 '10 at 05:20
  • I like the other answers below as well (especially cape1232's suggestion which is to use namespace root = MyFW::GameRoot, I did not know this particular C++ feature) but in this particular case, this answer works for me the best. I actually want to hide the call to Instance() as well. I am using Ogre3D and with Ogre, the calls are even longer, i.e. GetSinglestonPtr(), which is a pain to write everytime even with intellisense and wastes space. I can easily hover over root to see what it is if I want to. – Samaursa Jul 16 '10 at 19:08
  • @Georg First, I sense some annoyance at the fine distinctions I drew. I'm not criticizing, and I don't want to seem unfriendly. All the solutions here are good enough. But I still like `root=...` because you're hiding a namespace with a namespace. They're both the same thing. – cape1232 Jul 16 '10 at 20:23
  • Correct me if I'm wrong... You can actually require a compile to insert function code inline (the thing Georg Fritsche talks about) into a place where it is called from by ussing inline keyword (http://www.cppreference.com/wiki/keywords/inline). This is for compiles who don't support this – Sergej Andrejev Jul 17 '10 at 00:14
  • 1
    @sergej: Compilers are free to ignore `inline` and are also free to inline functions not marked as such. Todays compilers will inline aggressively either way, especially in simple cases like this. – Georg Fritzsche Jul 17 '10 at 15:13
  • @cap: Your comments read as pointing out mistakes to me. Sure, you yourself can post and use whatever approach you like, but don't assume its better without presenting correct facts. – Georg Fritzsche Jul 17 '10 at 16:29
1

The good way to do this (but never in a header) is

using MyFW::GameRoot;
GameRoot::Instance()->DoSomething;

This is a using declaration and is different from a using directive, which is what you mentioned above.

rlbond
  • 65,341
  • 56
  • 178
  • 228