Skip to main content
GameDev.net gamedev.net
🔒 Locked

Inlined Singleton Getter

Started by mak_hak Nov 4, 2006 at 6:10 PM 13 replies 1.8k views
Original Post
mak_hak
mak_hak
In an attempt to keep my code object-oriented and while trying to avoid the extra get() function call, I did the following: 1. Created a singleton class 2. Inlined the get() function 3. #define virtualInstanceName classname::get() This way, I use virtualInstanceName like a normal instance of the class and hopefully, avoid that extra call. It's working fine with me but I'd like to know what ppl think about this approach and whether it actually serves its purpose. I'm just experimenting.
Morpheus011
Morpheus011
inlining it is probably not doing anything for you as the compiler has the final say.

not sure why you do the #define, it's not really clarifying anything, you're not avoiding the "extra call" as this is simply replacing virtualInstanceName with the function call throughout your code in the preprocessor step, and it's actually more keys to type virtualInstanceName then it is to type classname::get(), so in effect this really kind of goes against the true purpose of using #defines.
mak_hak
mak_hak
virtualInstanceName is just for illustration purposes it could be myVar or foo or i. The #define ain't really important here. I added it just to skip the accessor.

I know this trick wouldn't work with all compilers but if the get() function is short (ie return classInstance) then the chances that it gets inlined are pretty high. or at least I'm hoping that.
jpetrie
jpetrie
Use it if you want, just be aware that

a) the "inline" probably gets you nothing, as previously mentioned
b) the #define practice is generally frowned upon
c) none of this has anything to do with making anything more "object oriented"
Sneftel
Sneftel
Quote:
Original post by mak_hak
It's working fine with me but I'd like to know what ppl think about this approach and whether it actually serves its purpose.

Well, that depends. What is its purpose?
mak_hak
mak_hak
I am starting to get suspicious with inline. Is it not implemeted in compilers?


jpetrie, I never said I was trying to make anything more object oriented. I just wanted to keep things in classes without having to make global functions or making all my methods static (which some ppl use as a replacement for singletons)
mak_hak
mak_hak
Quote:
Original post by Sneftel
Quote:
Original post by mak_hak
It's working fine with me but I'd like to know what ppl think about this approach and whether it actually serves its purpose.

Well, that depends. What is its purpose?


Having a single instance of a class and avoiding the get() call. An alternative to using static methods.

Morpheus011
Morpheus011
the compiler will only make a function inline if it has good reason to, which it wouldn't for most singleton Get methods. Even if it were to inline this method there would be no noticeable performance gain, which is why jpetrie and I told you that you gain nothing by making this function inline.

Don't think of it as a "trick"; there are limited circumstances when inline becomes useful.

I too am unclear what purpose you are trying to serve. Singletons require static methods, otherwise they aren't singletons. If you had to invoke the Get method from an object of the class, you've just defeated the whole purpose of having a singleton class. Making the function static means we don't have to instantiate the class in order to call the Get method. Just because you are doing the function call in a #define doesn't mean it shouldn't be static.

If the method isn't static then you will get compiler errors because you can't call non-static methods without instantiating the class.
MaulingMonkey
MaulingMonkey
Quote:
Original post by mak_hak
I am starting to get suspicious with inline. Is it not implemeted in compilers?


It's implemented in that compilers will inline functions and will grok the inline keyword. That said, the keyword is only a hint, and your compiler is completely free to ignore it (and they often do AFAIK). The compiler will usually decide what's best on it's own.

Quote:
jpetrie, I never said I was trying to make anything more object oriented. I just wanted to keep things in classes without having to make global functions or making all my methods static (which some ppl use as a replacement for singletons)


Most people would simply use a namespace (or a global) for this. It's certainly more kosher than using a #define to pretend a singleton is a global (which happens to be even longer than using the accessor in the first place ON TOP OF more obtuse to the reader), or far worse, not using ALL_CAPS for your macros. Hint hint.
Sneftel
Sneftel
Quote:
Original post by mak_hak
Having a single instance of a class

Certainly, although that problem has already been solved by the singleton.
Quote:
and avoiding the get() call.

Only if you mean "avoiding the appearance of a get() call". As I'm sure you already realize, the call is still taking place. The problem then becomes that the code is lying to the programmer. Good programmers avoid writing code which does that.
mak_hak
mak_hak
Quote:
Original post by MaulingMonkey
Quote:
jpetrie, I never said I was trying to make anything more object oriented. I just wanted to keep things in classes without having to make global functions or making all my methods static (which some ppl use as a replacement for singletons)


Most people would simply use a namespace (or a global) for this. It's certainly more kosher than using a #define to pretend a singleton is a global (which happens to be even longer than using the accessor in the first place ON TOP OF more obtuse to the reader), or far worse, not using ALL_CAPS for your macros. Hint hint.


:D MaulingMonkey, you're perfectly right. I didn't think about it this way. I wanted to give the client program the dot syntax. Maybe I shouldn't have mentioned the #define part at all.

Quote:

I too am unclear what purpose you are trying to serve. Singletons require static methods, otherwise they aren't singletons. If you had to invoke the Get method from an object of the class, you've just defeated the whole purpose of having a singleton class. Making the function static means we don't have to instantiate the class in order to call the Get method. Just because you are doing the function call in a #define doesn't mean it shouldn't be static.


Morpheus011, I see the point you're trying to make but I'll play the devil's advocate here. Lets say we have a logger class with a log() method which we want to use anywhere in our code. Now, I know our get() method has to be static but our log() method doesnt. And I dont want to make it static because I dont want the user to use it that way (or the user doesn't know how to use static methods). What would you do in this situation? You could use a namespace like MaulingMonkey said or you could trick everyone into thinking that they already have an instance of the class which they can use. (it's a trick in that sense at least).
mak_hak
mak_hak
Quote:
Original post by Sneftel
Quote:
and avoiding the get() call.

Only if you mean "avoiding the appearance of a get() call". As I'm sure you already realize, the call is still taking place. The problem then becomes that the code is lying to the programmer. Good programmers avoid writing code which does that.


Sneftel, would your answer change if we ignore I ever mentioned #define?
Sneftel
Sneftel
Of course. #define is how that code lies to the programmer, because it's how the code avoids an explicit get() call.
SecondBest
SecondBest
If I understand your goal correctly then what you're trying to achieve can be done using a handle class:

template<class T> class singleton_handle{    T* get()    {        static T k_val;        return &k_val;    }public:    operator T*(){return get();};	T* operator->(){return get();};	T& operator*(){return *get();};};struct X{    int x;};typedef singleton_handle<X> X_singleton;int main(){    X_singleton A;    A->x = 0;    X_singleton B;    ++(*B).x;    // here A and B actually refer to the same object    cout<< A->x<<endl;//should print 1;    return 0;}


The template functions should be easy for the compiler to inline, so it should not incur much (if any) overhead.

This method allows you to USE class X as a singleton, and still allow others to use it in whatever manner they see fit.

make sure to specialize the template for classes with no default constructors.

I wrote this code off the top of my head to demonstrate the technique. I haven't really tested it so it might contain an error or seven. Use at your own risk.

Peace Out!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.