Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length

 
Advanced search

879204 Posts in 32968 Topics- by 24359 Members - Latest Member: colinvella

May 23, 2013, 01:31:49 PM
TIGSource ForumsDeveloperTechnical (Moderators: Glaiel-Gamer, ThemsAllTook)Playing it silly with Singleton and static
Pages: 1 [2] 3
Print
Author Topic: Playing it silly with Singleton and static  (Read 2678 times)
Average Software
Level 10
*****

Fleeing all W'rkncacnter


View Profile WWW Email
« Reply #15 on: June 24, 2010, 05:00:50 AM »

I not sure how well known this is, but I use a similar sort of technique when I need something akin to a finally block in C++.  Sometimes I need cleanup code that's more complex than what auto_ptr can provide, so I use a local object destructor, something like this:

Code:
void SomeFunction()
{
    struct Finalizer
    {
        Finalizer(Obj thing_to_clean)
        :thing_to_clean(thing_to_clean)
        {
        }

        ~Finalizer()
        {
            // Do the clean up with thing_to_clean.
        }

        Obj &thing_to_clean;
    } finally(the_thing);

    // The rest of the code.
}

This is also a great way of faking nested functions, something I think C++ sorely needs.
Logged

Franchise - The restaurant wars begin!

What would John Carmack do?
muku
Level 10
*****



View Profile WWW
« Reply #16 on: June 24, 2010, 05:58:54 AM »

I not sure how well known this is, but I use a similar sort of technique when I need something akin to a finally block in C++.  Sometimes I need cleanup code that's more complex than what auto_ptr can provide, so I use a local object destructor, something like this:

I think Alexandrescu and Marginean have proposed "scope guards" as a library solution for this kind of thing, though theirs also handles the case where you want to execute some code only in the case of failure (if an exception is thrown). Might be overkill for your simple example maybe, but I do like the idea of hiding implementation details (using a destructor to execute the code).

By the way, the D language has scope guards (for success, failure and unconditional ones) built in which makes this kind of thing very pleasant to do. It really changes the way you do error handling.
Logged

The Cosyne Synthesis Engine - realtime music synthesis for games
Average Software
Level 10
*****

Fleeing all W'rkncacnter


View Profile WWW Email
« Reply #17 on: June 24, 2010, 07:10:02 AM »

By the way, the D language has scope guards (for success, failure and unconditional ones) built in which makes this kind of thing very pleasant to do. It really changes the way you do error handling.

I had to learn Python for work, and although the more I use it, the more I come to hate it, it's try-except-finally-else construct is a nice way of handling that.

I come across this sort of situation very rarely in C++, so I'm not sure it needs something to explicitly handle these cases.  I still want nested functions, though.
Logged

Franchise - The restaurant wars begin!

What would John Carmack do?
muku
Level 10
*****



View Profile WWW
« Reply #18 on: June 24, 2010, 07:57:53 AM »

By the way, the D language has scope guards (for success, failure and unconditional ones) built in which makes this kind of thing very pleasant to do. It really changes the way you do error handling.

I had to learn Python for work, and although the more I use it, the more I come to hate it, it's try-except-finally-else construct is a nice way of handling that.

It's terribly verbose though. Especially if you don't want to catch any exceptions, the following code is much more concise:
Code:
void foo()
{
  auto x = acquire();
  scope(exit) dispose(x);

  // do stuff here that might throw...
}
It has the additional advantage of grouping the acquisition and the disposal together logically, instead of tearing them apart.

Quote
I come across this sort of situation very rarely in C++, so I'm not sure it needs something to explicitly handle these cases.  I still want nested functions, though.

Yeah. D has those too Tongue  Wouldn't want to live without them anymore.
Logged

The Cosyne Synthesis Engine - realtime music synthesis for games
Average Software
Level 10
*****

Fleeing all W'rkncacnter


View Profile WWW Email
« Reply #19 on: June 24, 2010, 08:11:11 AM »

It's terribly verbose though. Especially if you don't want to catch any exceptions, the following code is much more concise:
Code:
void foo()
{
  auto x = acquire();
  scope(exit) dispose(x);

  // do stuff here that might throw...
}
It has the additional advantage of grouping the acquisition and the disposal together logically, instead of tearing them apart.

How is that any different than just using a local object?

Code:
void funk()
{
    Something thing;

    // Destroyed at end of scope.
}
Logged

Franchise - The restaurant wars begin!

What would John Carmack do?
muku
Level 10
*****



View Profile WWW
« Reply #20 on: June 24, 2010, 08:41:47 AM »

How is that any different than just using a local object?

You have to declare the class first, that's a lot of boilerplate code. Especially if many of these uses are one-off things, you litter your code with classes which you don't really needed in the first place. Look at the example you posted further up: 14 lines for the Finalizer struct. If you want to execute just one line of code at the end of the scope, that's a hell of a lot of overhead.
Logged

The Cosyne Synthesis Engine - realtime music synthesis for games
Average Software
Level 10
*****

Fleeing all W'rkncacnter


View Profile WWW Email
« Reply #21 on: June 24, 2010, 08:57:51 AM »

How is that any different than just using a local object?

You have to declare the class first, that's a lot of boilerplate code. Especially if many of these uses are one-off things, you litter your code with classes which you don't really needed in the first place. Look at the example you posted further up: 14 lines for the Finalizer struct. If you want to execute just one line of code at the end of the scope, that's a hell of a lot of overhead.

I guess I just don't understand the language then, what are acquire() and dispose()?
Logged

Franchise - The restaurant wars begin!

What would John Carmack do?
muku
Level 10
*****



View Profile WWW
« Reply #22 on: June 24, 2010, 09:01:42 AM »

I guess I just don't understand the language then, what are acquire() and dispose()?

Ah sorry, that's not part of the language. Those were just examples to illustrate a possible use. More real life example:

Code:
void main()
{
  SDL_Init();
  scope(exit) SDL_Terminate();

  // game main loop etc
}
Logged

The Cosyne Synthesis Engine - realtime music synthesis for games
Average Software
Level 10
*****

Fleeing all W'rkncacnter


View Profile WWW Email
« Reply #23 on: June 24, 2010, 09:04:27 AM »

I guess I just don't understand the language then, what are acquire() and dispose()?

Ah sorry, that's not part of the language. Those were just examples to illustrate a possible use. More real life example:

Code:
void main()
{
  SDL_Init();
  scope(exit) SDL_Terminate();

  // game main loop etc
}

Ah, so it's like C's atexit() function, but locally scoped.
Logged

Franchise - The restaurant wars begin!

What would John Carmack do?
muku
Level 10
*****



View Profile WWW
« Reply #24 on: June 24, 2010, 09:11:55 AM »

Ah, so it's like C's atexit() function, but locally scoped.

Yup, you might say so, minus the runtime overhead (I imagine atexit() puts something into a table or list which has to be checked when the program exits, while scope() is completely static). Plus you get scope(success) and scope(failure) which trigger only when no exception/an exception occurs.
Logged

The Cosyne Synthesis Engine - realtime music synthesis for games
Average Software
Level 10
*****

Fleeing all W'rkncacnter


View Profile WWW Email
« Reply #25 on: June 24, 2010, 09:12:35 AM »

I guess I just don't understand the language then, what are acquire() and dispose()?

Ah sorry, that's not part of the language. Those were just examples to illustrate a possible use. More real life example:

Code:
void main()
{
  SDL_Init();
  scope(exit) SDL_Terminate();

  // game main loop etc
}

Ah, so it's like C's atexit() function, but locally scoped.


As a point of interest, you could do the same thing in C++0x like so:

Code:
template <typename Callable>
struct ScopedCleanup
{
    ScopedCleanup(Callable &callable)
    :callable(callable)
    {
    }

    ~ScopedCleanup()
    {
        callable();
    }

    Callable &callable;
};

#define CALL_AT_EXIT(cleanup) ScopedCleanup<decltype(cleanup)> sc##cleanup(cleanup)

void funk()
{
    CALL_AT_EXIT(SomeFunction);

    // stuff
}

With C++0x variadic templates and C99/C++0x variadic macros, you could even attach parameters to them.
« Last Edit: June 24, 2010, 09:23:39 AM by Average Software » Logged

Franchise - The restaurant wars begin!

What would John Carmack do?
Linus
Level 0
***


View Profile Email
« Reply #26 on: June 27, 2010, 11:48:55 PM »

Each entry in the menu was a separate class

It strikes me that this was your real problem.

...That was uncalled for?
Each menu item is a disparate scene setup with different logic and structure, which is rendered in an off-screen buffer to a quad texture and displayed in the menu. Moving to a scripting language, which could allow me to merge the scenes into a single class, is not an interesting option as of now either, since there's too much work involved in such a move.
Can you still uphold your baseless statement?

In a more relevant discussion, boost also has some nice examples of scoped features, most prominently I like their scoped mutex implementations that also come in recursive versions that add another level of 'Oooh'.

At the same time, they also have a completely different solution to on scope exit where they use a macro to build the previously mentioned classes, with the added differentiation that you specify the code to execute on exit in place, rather than in an external function. May suit some tastes. Shrug
Logged
Jonathan Whiting
Level 2
**



View Profile WWW
« Reply #27 on: June 28, 2010, 01:06:36 AM »

Each entry in the menu was a separate class

It strikes me that this was your real problem.

...That was uncalled for?
Each menu item is a disparate scene setup with different logic and structure, which is rendered in an off-screen buffer to a quad texture and displayed in the menu. Moving to a scripting language, which could allow me to merge the scenes into a single class, is not an interesting option as of now either, since there's too much work involved in such a move.
Can you still uphold your baseless statement?

I'm sorry, I have an impulsive dislike of OOP 'tricks' like the ones you described in the initial post (in a similar vein I prefer straight C to C++, though I use both).  I pretty strongly believe that when you start trying to answer complicated architecture questions as above you should step back and start asking why you've reached that point in the first place.

I genuinely didn't mean to cause offense, just to point out the area that to me the assumptions looked shakier than the solution.  I was overly blunt.  Sorry again.
Logged

BorisTheBrave
Level 10
*****


View Profile WWW
« Reply #28 on: June 28, 2010, 12:36:33 PM »

Each menu item is a disparate scene setup with different logic and structure,
I think that's the source of confusion. When I think of menu's I think homogenous buttons, for which classes are inappropriate.
Logged
Jonathan Whiting
Level 2
**



View Profile WWW
« Reply #29 on: June 28, 2010, 11:13:39 PM »

Each menu item is a disparate scene setup with different logic and structure,
I think that's the source of confusion. When I think of menu's I think homogenous buttons, for which classes are inappropriate.

Yes, that was certainly the mental image that it conjured for me.
Logged

Pages: 1 [2] 3
Print
Jump to:  

Theme orange-lt created by panic