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

Login with username, password and session length

 
Advanced search

1075922 Posts in 44152 Topics- by 36120 Members - Latest Member: Royalhandstudios

December 29, 2014, 03:45:53 PM
TIGSource ForumsDeveloperTechnical (Moderators: Glaiel-Gamer, ThemsAllTook)Simplification
Pages: [1]
Print
Author Topic: Simplification  (Read 960 times)
theman515
Level 0
**


The code... the code!!


View Profile WWW Email
« on: December 22, 2011, 01:56:29 AM »

Hey guys, I'm writing a console for my side-scrolling shoot-em-up and I'm currently writing a command to change certain variables of a specific object. the command goes through a list of objects that are all derived from the same class but they themselves are different classes and assigns the correct object to a pointer.

Now I run into a problem, currently my code looks like so:
Code:
if(refID == Lance::Ref)
    Lance obj*;
if(refID == Floor::Ref)
    Floor obj*;

which is fine now when I only have 2 test classes but when I start adding objects into the universe the chance for error and forgetting something becomes really high. My question is: is there an easier way to do what I'm doing? Thanks in advance  Gentleman
Logged
Netsu
Level 10
*****


proficient at just chillin'


View Profile WWW
« Reply #1 on: December 22, 2011, 02:26:14 AM »

As long as this is C++:
I think a more elegant solution would be to always create a pointer to the base class from which all those are derived, and assign the object to this pointer.
Logged

bauer
Level 1
*



View Profile WWW Email
« Reply #2 on: December 22, 2011, 02:50:25 AM »

How are your objects structured? You say that they're all derived from the same base class? Does each object have a unique ID or is the ID unique per object type (per class basically)?

I also agree that this sounds like a problem best solved by a general interface using pointers to the base class and virtual methods.
Logged

theman515
Level 0
**


The code... the code!!


View Profile WWW Email
« Reply #3 on: December 22, 2011, 01:14:27 PM »

Netsu: I tried that, and it works for any variable inherited by the superclass but there are some variables unique to each child class that i need to change and yes,this is C++.

bauer: they all come from a class named IScreenElement and have 3 virtual functions: render(), onFrame(), and init(). each child class has a refID which is unique to each class type and a uniqueID which is unique to each individual object and gets created when the object initializes.

I could just make the specific functions that edit the variables virtual functions but seeing as I would only use these functions for one class I figured it would be a huge waste of resources.
Logged
Netsu
Level 10
*****


proficient at just chillin'


View Profile WWW
« Reply #4 on: December 22, 2011, 01:18:10 PM »

Netsu: I tried that, and it works for any variable inherited by the superclass but there are some variables unique to each child class that i need to change and yes,this is C++.

You can always cast the pointer to the correct type when the need comes to access the unique variables/methods.
Logged

theman515
Level 0
**


The code... the code!!


View Profile WWW Email
« Reply #5 on: December 22, 2011, 01:21:08 PM »

like this (type)variable->function()?
Logged
Netsu
Level 10
*****


proficient at just chillin'


View Profile WWW
« Reply #6 on: December 22, 2011, 01:24:19 PM »

Yes, although you might need additional parentheses, I'm not sure, in your case it would look like this:
Code:
((Lance*)obj)->function();
Logged

theman515
Level 0
**


The code... the code!!


View Profile WWW Email
« Reply #7 on: December 22, 2011, 01:40:48 PM »

Works wonderfully, thanks Netsu  Beer!
Logged
Netsu
Level 10
*****


proficient at just chillin'


View Profile WWW
« Reply #8 on: December 22, 2011, 01:45:34 PM »

Not a problem Gentleman
Logged

BlueSweatshirt
Level 10
*****

the void


View Profile WWW
« Reply #9 on: December 22, 2011, 10:38:51 PM »

Couldn't you reduce all this bloat by making function() virtual?
Like, even if the variables being changed are different you could just pass a generic string into function() to generalize it. It's easy enough to pull a number out of a string.

Or is there something I'm missing?  Waaagh!
Logged

Netsu
Level 10
*****


proficient at just chillin'


View Profile WWW
« Reply #10 on: December 23, 2011, 01:15:54 AM »

That's also neat, I don't know which is considered 'better practice'.
Logged

BlueSweatshirt
Level 10
*****

the void


View Profile WWW
« Reply #11 on: December 23, 2011, 02:26:34 AM »

Well I think virtual is the 'better practice' because it removes the need for him to write that redundant, lengthy code to transform an object for each case. It would make implementing new objects easier and his code would have less bloat.

Of course, this is assuming he's trying to editing data that can be represented by text easily enough. I assume this is for a debug console or something.

If he is looking to do something more complicated like passing image data he could always encode it, at the loss of time of course. The other option would be to take the often-shunned-but-equally-effective function(void* param) route and cast it as your desired data type inside of your function implementation.
Logged

Klaim
Level 10
*****



View Profile WWW
« Reply #12 on: December 23, 2011, 02:29:15 AM »

Obviously, using virtual is the good practice. That's precisely the kind of case why they exist and one of the goals is to avoid totally casts.


Because casts are problematic. In your suggestion you're casting someting into something else without knowing if it's the right type, not checked at compile-time or run-time, so the day you pass something that you didn't manage in this code you'll enter "undefined behaviour" land.

Also, if you're forced to use a cast, then use C++ casts, not C cast because C cast is not safe at all. C++ casts does each one and only one thing and are ugly enough to be noticed by the user easily, or searched in the code base. static_cast only convert at compile-time a pointer or reference into the type hierarchy. dynamic_cast does the same but at runtime and if you use a reference it will throw an exception, if you use a pointer you can get a nullptr pointer meaning the cast failed (but it obviously have a cost on execution speed). const_cast allow switching from const to non-const and vice-versa, and reinterpret_cast tells the compiler to do "whatever it can" to cast, almost the same as C cast but at least you have an obvious point in the code to see what the hell you were doing at that moment.


So, for the simplification : have a common interface with a virtual function.

IF you want to plug functions or functors only (if you don't need to have a specific full interface), you could also manage std::function  objects, that would make the abstraction with "anything that can be called with ()".

If you can, don't use casts. Casts are for those ugly cases where you need to dirt your hands with raw memory or when you need to manage data from other binaries that you have to make the compiler make sure it's of the wanted types.
Logged

http://www.klaimsden.net | Game : NetRush | Digital Story-Telling Technologies : Art Of Sequence
Netsu
Level 10
*****


proficient at just chillin'


View Profile WWW
« Reply #13 on: December 23, 2011, 02:33:57 AM »

Thanks guys, that's good to know Smiley
Should I always have one virtual method that contains all the custom behaviour for each sub class or do something else if I need more than one logical functionality added?
Logged

BorisTheBrave
Level 10
*****


View Profile WWW
« Reply #14 on: December 23, 2011, 04:33:17 AM »

You should have one virtual method for each logically distinct behaviour, just like regular methods.

The Visitor pattern may also be handy to you - it's the equivalent of virtual methods, except you don't have to specify the methods with the classes.

Also possible for your specific case is reflection (which requires work to hack into C++). But I'd go with virtual methods until you find they are cluttering too much.
Logged
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic