Jump to content

  • Log In with Google      Sign In   
  • Create Account

static class vs this?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
22 replies to this topic

#1 nuclear123   Members   -  Reputation: 119

Like
0Likes
Like

Posted 30 March 2011 - 12:26 PM

is there a difference/overhead in doing this....

class Log
{
private: // no members
public:
       void createLog( );
};

int main()
{

Log log1;
log1.createLog();

}



class Log
{
private: // no members
public:
       static void createLog( );
};


int main()
{
Log::createLog();
}

is this the same exact code? or does the non static one create useless overhead and is bad code/slower

Sponsor:

#2 frob   Moderators   -  Reputation: 21315

Like
1Likes
Like

Posted 30 March 2011 - 01:12 PM

No, they are not the same.

A static member function does not operate on an object.
A non-static member function must have an object, which is automatically passed to the function as the this pointer.

The performance difference between the two is very nearly nothing.


Generally you use a static member function when you want a function to be part of a class interface but you won't actually reference a part of the object. For example, you may use it to look up common values.

I'm guessing that eventually createLog is going to modify the state of a Log object, so it shouldn't be a static function.
Check out my personal indie blog at bryanwagstaff.com.

#3 way2lazy2care   Members   -  Reputation: 782

Like
0Likes
Like

Posted 30 March 2011 - 01:22 PM

This looks eerily like you are going to implement singletons...

#4 GothSeiDank   Members   -  Reputation: 156

Like
-3Likes
Like

Posted 30 March 2011 - 01:26 PM

If you want Log to be available with the same instance everywhere, think about using a Singleton.

class Log : public boost::noncopyable
{
private:
 	Log()
	{}

public:
 	static Log& getInstance()
	{
 		static Log OnlyOne;
 		return OnlyOne;
	}

	void createLog() 
	{
 		// .....
	}

   void logIt(int, string&)
   {}
};

#define LOGERROR(s)	Log::getInstance().logIt(L_ERROR, s)

int main()
{
	Log::getInstance().createLog();
	LOGERROR("I am feeling depressed.");
}

Static Values can also be used to define Strings or things used over the whole program:
class Math
{
	static double PI;
};

double Math::PI = 3.14159265;

int main()
{
	using namespace std;
	cout << "PI is exactly: " << Math::PI << endl;
}

If you say "pls", because it is shorter than "please", I will say "no", because it is shorter than "yes"
http://nightlight2d.de/

#5 scgames   Members   -  Reputation: 1977

Like
0Likes
Like

Posted 30 March 2011 - 11:17 PM

If you want Log to be available with the same instance everywhere, think about using a Singleton.

Why not just use a global?

#6 Hodgman   Moderators   -  Reputation: 30385

Like
0Likes
Like

Posted 30 March 2011 - 11:35 PM

I'd expect a modern compiler to create the same code for both cases.

The only difference is that one is an evil global, and one isn't.

#7 rip-off   Moderators   -  Reputation: 8222

Like
1Likes
Like

Posted 31 March 2011 - 03:42 AM

If logging is your bottleneck then you are doing it wrong. In any case with logging the slow part is usually the I/O, not the function calls themselves. Don't micro optimise unless you have a performance problem and you have exhausted macro optimisations.

#8 GothSeiDank   Members   -  Reputation: 156

Like
0Likes
Like

Posted 31 March 2011 - 03:59 AM


If you want Log to be available with the same instance everywhere, think about using a Singleton.

Why not just use a global?


Of course could he use a global, but in my eyes a singleton provides a cleaner access-interface.
If you say "pls", because it is shorter than "please", I will say "no", because it is shorter than "yes"
http://nightlight2d.de/

#9 rip-off   Moderators   -  Reputation: 8222

Like
1Likes
Like

Posted 31 March 2011 - 04:58 AM

I believe a Singleton provides a worse interface. It tends to be more verbose, and it is harder to create sub-system local log instances. For example, you might want to set the log verbosity of your graphics subsystem to high, while keeping others low. For low complexity games, I'd probably just use simple procedure calls rather than create a class at all. Any state can be kept in an anonymous namespace.

Or just use std::cout, std::cerr and std::clog directly. I might modify their rdbuf() to output to a in-game console or to a file, or I might use OS-level pipes to capture the output to a file.

#10 GothSeiDank   Members   -  Reputation: 156

Like
0Likes
Like

Posted 31 March 2011 - 05:09 AM

I believe a Singleton provides a worse interface. It tends to be more verbose, and it is harder to create sub-system local log instances. For example, you might want to set the log verbosity of your graphics subsystem to high, while keeping others low. For low complexity games, I'd probably just use simple procedure calls rather than create a class at all. Any state can be kept in an anonymous namespace.

Or just use std::cout, std::cerr and std::clog directly. I might modify their rdbuf() to output to a in-game console or to a file, or I might use OS-level pipes to capture the output to a file.


When you use a singleton, it is guaranteed that you cannot access the singleton before it is created. Hence getInstance().
You don't have that guarantee with static globals.

I use such a logging singleton for creating html logs. You can represent debugging data much better with that when you are unable to pause the process because it depends on timing etc, which is esp. the case when you are doing games. Well, at least it is an easy method to achieve this.
I made myself a class log and logwriter. logwriter can be derived and output any format such as csv, text or html.
If you say "pls", because it is shorter than "please", I will say "no", because it is shorter than "yes"
http://nightlight2d.de/

#11 scgames   Members   -  Reputation: 1977

Like
0Likes
Like

Posted 31 March 2011 - 05:16 AM

When you use a singleton, it is guaranteed that you cannot access the singleton before it is created. Hence getInstance().
You don't have that guarantee with static globals.

How about something like (not compiled or tested):

// In a header file somewhere:
Log& GetLog();

// In a source file:
Log& GetLog()
{
    static Log log;
    return log;
}
In this case the instance will be created the first time it's accessed, just like with your 'get instance' method, correct? Assuming that's correct and I'm not overlooking anything, what advantages does the singleton method have over something like the above?

#12 GothSeiDank   Members   -  Reputation: 156

Like
0Likes
Like

Posted 31 March 2011 - 05:20 AM

Uhm, what you are doing has only 1 difference to a singleton:
The get-function is not a member of the class. That would be unintuitive for me.
With global normally one means rather this:

Log g_log;

int main()
{
   g_log.doSomething();
}

And thats not advised for the reasons above. Of course, in 1 source file it does not matter at all. But if you have a complex project, Singletons are the way to go over global Objects. In my Opinion. :)

edit: One must be careful not to create too many singletons. Using it too much and too often can lead to bad design. Experienced this myself.
If you say "pls", because it is shorter than "please", I will say "no", because it is shorter than "yes"
http://nightlight2d.de/

#13 scgames   Members   -  Reputation: 1977

Like
0Likes
Like

Posted 31 March 2011 - 05:31 AM

Uhm, what you are doing has only 1 difference to a singleton:

Are you sure? With the method I posted above, I can create additional loggers wherever and whenever needed. So that's at least two differences, and it's a pretty significant difference at that ;)

Singletons are the way to go over global Objects.

But why?

#14 GothSeiDank   Members   -  Reputation: 156

Like
0Likes
Like

Posted 31 March 2011 - 05:39 AM

Well, yes okay, you are free to have more loggers than 1 and you are not restricting the class. Thats right, my bad.
But that isn't a global object then by definition.
In fact, I use it like this, but I have one singleton in my App which offers a "systemwide" logbook.
http://code.google.com/p/nightlight2d/source/browse/trunk/NightLightDLL/NLSystemController.hpp


But why?


If you have globals and meaning real globals, not static functions, it is not guaranteed that global1 in compilation unit 1 is created before global2 in compilation unit 2 is accessing it.
At least to my knowledge of the c++ standard in this case. Also, a global always uses the memory it needs, a singleton only if it is used at all.
If you say "pls", because it is shorter than "please", I will say "no", because it is shorter than "yes"
http://nightlight2d.de/

#15 rip-off   Moderators   -  Reputation: 8222

Like
0Likes
Like

Posted 31 March 2011 - 05:53 AM

When you use a singleton, it is guaranteed that you cannot access the singleton before it is created. Hence getInstance().

I have only a handful of globals, all of which are totally independent of one another. A global logger, sometimes, a global resource cache (does nothing on construction) and rarely anything else. I've used the trick jyk showed before for managing the resource cache, in my newer code bases I simply don't make it global.

If you have globals and meaning real globals, not static functions...

We mean a value that is globally accessible (somehow).

...it is not guaranteed that global1 in compilation unit 1 is created before global2 in compilation unit 2 is accessing it.
At least to my knowledge of the c++ standard in this case. Also, a global always uses the memory it needs, a singleton only if it is used at all.

There are also potential multi-threaded issues with the delayed initialisation of global values. I tend not to worry about the memory usage, as the few globals I have are pretty much always used, unless the program shuts down because the configuration is completely corrupt.

#16 scgames   Members   -  Reputation: 1977

Like
0Likes
Like

Posted 31 March 2011 - 05:56 AM

Yes, the 'static initialization order fiasco' is certainly something to be aware of, but the method shown in my example above shouldn't be susceptible to that. Also, it doesn't suffer from the (usually artificial) limitation that there be only one, and it requires less support code than a singleton. Granted, the difference in complexity is minimal, but I don't see any particular reason to make things more complex than they would be otherwise, just so you can impose a constraint that probably isn't needed anyway.

#17 Hodgman   Moderators   -  Reputation: 30385

Like
0Likes
Like

Posted 31 March 2011 - 06:14 AM

[holywar]
...Or just don't use globals, ever (nor singletons, which are just as evil).



P.S. there is no "[/holywar]" tag. good luck.

#18 NEXUSKill   Members   -  Reputation: 458

Like
0Likes
Like

Posted 31 March 2011 - 09:32 AM

May I just throw this out there? Multiton? although I think we drifted far away from the question which I think was much more basic.
Game making is godlike

LinkedIn profile: http://ar.linkedin.com/pub/andres-ricardo-chamarra/2a/28a/272



#19 Zahlman   Moderators   -  Reputation: 1682

Like
0Likes
Like

Posted 31 March 2011 - 05:22 PM

Here's a radical idea: have you considered not making a class at all?

I'm pretty sure people used to do logging in the pre-Stroustrup era. I'm also pretty sure that the normal approach to logging in C did not involve the 'struct' keyword.

#20 return0   Members   -  Reputation: 444

Like
-1Likes
Like

Posted 31 March 2011 - 07:21 PM

Don't use singletons - ffs, don't waste time writing logs, use an off the shelf.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS