Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  
Pages: 1 ... 342 343 [344] 345 346 ... 796

Author Topic: if self.isCoder(): post() #Programming Thread  (Read 884745 times)

Skyrunner

  • Bay Watcher
  • ?!?!
    • View Profile
    • Portfolio
Re: if self.isCoder(): post() #Programming Thread
« Reply #5145 on: October 29, 2013, 06:47:02 am »

When you store the INHx pointers in a vector<BASE *> they are implicitly cast to that type, so your overloads of idenitfy will definitely not do what you wish. But as you can see the correct reimplemented virtual function is called, so that's what you have to work with.

The cleanest is to make a virtual id() function (return an int or enum or whatever), reimplement for each inheriting class and test against that in identify(BASE id). The alternative is dynamic_cast and test for non-NULL, which tends to be discouraged (but is sometimes useful).

It's pretty sad that what would seem like a perfect usage of OOP-thingies doesn't actually work in C++. :(

The fun thing is, I have been working on a project that adds some reflection to C++ classes. The ReflectBase class and Reflect.h header file are where most of the work is done. Note that this requires using GCC, as it uses the GNU C++ ABI functions. I'm not sure if MSVC has a compatible set of functions.
Darn, I guess I won't be using those. o_O
Logged

bay12 lower boards IRC:irc.darkmyst.org @ #bay12lb
"Oh, they never lie. They dissemble, evade, prevaricate, confoud, confuse, distract, obscure, subtly misrepresent and willfully misunderstand with what often appears to be a positively gleeful relish ... but they never lie" -- Look To Windward

MorleyDev

  • Bay Watcher
  • "It is not enough for it to just work."
    • View Profile
    • MorleyDev
Re: if self.isCoder(): post() #Programming Thread
« Reply #5146 on: October 29, 2013, 07:35:57 am »

It's not clean, but there is a pattern that can work. If you typeid and store the address of the result of that with your type, and then use another map to map between handling functions. I usually use this when I can give it to the container in it's fullest form via templatyes, and then you pull it in it's fullest form, and hide that it gets turned to an interim type.

But honestly, if you're relying on this behaviour at a high level (I only really find need of it it for type-safe event systems) it's usually a design flaw, a sign either your base classes do too much or your higher level classes do too little.
Logged

Skyrunner

  • Bay Watcher
  • ?!?!
    • View Profile
    • Portfolio
Re: if self.isCoder(): post() #Programming Thread
« Reply #5147 on: October 29, 2013, 07:53:26 am »

Code: [Select]
if (part->type() == "cannon")
      {
      auto partpointer = dynamic_cast<ShipCannons*>(part);
      getProfile(*partpointer, line);
      }
    else if (part->type() == "armor")
      {
      auto partpointer = dynamic_cast<ShipArmor*>(part);
      getProfile(*partpointer, line);
      }
    else if (part->type() == "statue")
      {
      auto partpointer = dynamic_cast<ShipStatue*>(part);
      getProfile(*partpointer, line);
      }
    else if (part->type() == "sails")
      {
      auto partpointer = dynamic_cast<ShipSails*>(part);
      getProfile(*partpointer, line);
      }

This is the code I went with. It's pretty much what you said, map between handling functions. getProfile() is overloaded for each derived class.
Logged

bay12 lower boards IRC:irc.darkmyst.org @ #bay12lb
"Oh, they never lie. They dissemble, evade, prevaricate, confoud, confuse, distract, obscure, subtly misrepresent and willfully misunderstand with what often appears to be a positively gleeful relish ... but they never lie" -- Look To Windward

olemars

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #5148 on: October 29, 2013, 07:57:04 am »

What in the getProfile overloads require that the pointer is of the derived type?
Logged

Siquo

  • Bay Watcher
  • Procedurally generated
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #5149 on: October 29, 2013, 08:02:13 am »

What in the getProfile overloads require that the pointer is of the derived type?
Yeah, it's this what I don't get. Most of the fun of inheritance is that it shouldn't matter which of the derived classes it is.
Logged

This one thread is mine. MIIIIINE!!! And it will remain a happy, friendly, encouraging place, whether you lot like it or not. 
will rena,eme sique to sique sxds-- siquo if sucessufil
(cant spel siqou a. every speling looks wroing (hate this))

Skyrunner

  • Bay Watcher
  • ?!?!
    • View Profile
    • Portfolio
Re: if self.isCoder(): post() #Programming Thread
« Reply #5150 on: October 29, 2013, 08:10:39 am »

What in the getProfile overloads require that the pointer is of the derived type?
Yeah, it's this what I don't get. Most of the fun of inheritance is that it shouldn't matter which of the derived classes it is.
I know, but the thing is.


Spoiler (click to show/hide)

As I detailed in the quote in the spoiler, I want to store all my ___Parts in a single vector, but the very act of storing a class in a vector in C++ obliterates its identity as a derived class :( In an ideal world I'd just call getProfile(**part) and the compiler would do all the magic for me.


.. Am I missing something?
« Last Edit: October 29, 2013, 08:15:24 am by Skyrunner »
Logged

bay12 lower boards IRC:irc.darkmyst.org @ #bay12lb
"Oh, they never lie. They dissemble, evade, prevaricate, confoud, confuse, distract, obscure, subtly misrepresent and willfully misunderstand with what often appears to be a positively gleeful relish ... but they never lie" -- Look To Windward

olemars

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #5151 on: October 29, 2013, 08:24:35 am »

It doesn't obliterate its identity. The onlooker just sees the object then and there as an instance of the parent class, but if you ask the object something it will behave like the derived class it really is.

The only time you really need a pointer to an object of the derived class is during creation or if you've extended the interface and need to call a function not declared in the parent class.
Logged

Siquo

  • Bay Watcher
  • Procedurally generated
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #5152 on: October 29, 2013, 08:29:22 am »

.. Am I missing something?
I'm not able to try it out, but what if you remove identify(BASE obj)? That will force the runtime to find a better match.
Logged

This one thread is mine. MIIIIINE!!! And it will remain a happy, friendly, encouraging place, whether you lot like it or not. 
will rena,eme sique to sique sxds-- siquo if sucessufil
(cant spel siqou a. every speling looks wroing (hate this))

olemars

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #5153 on: October 29, 2013, 08:38:02 am »

You can't implicitly downcast like that.
Logged

Siquo

  • Bay Watcher
  • Procedurally generated
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #5154 on: October 29, 2013, 08:44:12 am »

No, I just tried it, it feeds a BASE* of course. Duh.
* Siquo smacks forehead

Anyway, the proper solution would be for "identify" to be on the BASE object (such as myName is). The problem with your solution is that every time you add a new derived class, you also need to add stuff outside of that object pertaining to that object, leading to spaghetti.

I know this sounds a lot like the hated "you should not be doing that in the first place"-type "solutions", but I implore you to see if it's not possible to have a more generic outside function that can handle any type of BASE, using (either virtual or not) methods of that BASE (or derived) object, without it knowing what type of BASE it is.
Logged

This one thread is mine. MIIIIINE!!! And it will remain a happy, friendly, encouraging place, whether you lot like it or not. 
will rena,eme sique to sique sxds-- siquo if sucessufil
(cant spel siqou a. every speling looks wroing (hate this))

ECrownofFire

  • Bay Watcher
  • Resident Dragoness
    • View Profile
    • ECrownofFire
Re: if self.isCoder(): post() #Programming Thread
« Reply #5155 on: October 29, 2013, 08:54:45 am »

Why not just have getProfile(line) as a virtual member function?

The cleanest solution when dealing with polymorphism is... more polymorphism!
Logged

Skyrunner

  • Bay Watcher
  • ?!?!
    • View Profile
    • Portfolio
Re: if self.isCoder(): post() #Programming Thread
« Reply #5156 on: October 29, 2013, 09:57:00 am »

No, I just tried it, it feeds a BASE* of course. Duh.
* Siquo smacks forehead

Anyway, the proper solution would be for "identify" to be on the BASE object (such as myName is). The problem with your solution is that every time you add a new derived class, you also need to add stuff outside of that object pertaining to that object, leading to spaghetti.

I know this sounds a lot like the hated "you should not be doing that in the first place"-type "solutions", but I implore you to see if it's not possible to have a more generic outside function that can handle any type of BASE, using (either virtual or not) methods of that BASE (or derived) object, without it knowing what type of BASE it is.
Well, if I wrap my current solution in a function that's exactly what it is xD
Or if I'm understanding it wrong: because C++ doesn't have reflection or stuff, and because that function is intimately tied to what data the derived class has, I can't make a more generic function than this.

Why not just have getProfile(line) as a virtual member function?

The cleanest solution when dealing with polymorphism is... more polymorphism!

This seems to be a pretty solid idea, though in my specific case it's a bit clunky. O.o
Logged

bay12 lower boards IRC:irc.darkmyst.org @ #bay12lb
"Oh, they never lie. They dissemble, evade, prevaricate, confoud, confuse, distract, obscure, subtly misrepresent and willfully misunderstand with what often appears to be a positively gleeful relish ... but they never lie" -- Look To Windward

Mego

  • Bay Watcher
  • [PREFSTRING:MADNESS]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #5157 on: October 29, 2013, 03:32:44 pm »

I did some research - MSVC has a function that can supposedly demangle type names, but apparently it doesn't work unless the type is in the global scope. If it's a nested type or inside of a namespace, it doesn't work.

Unfortunately, it looks like your options are as follows:

1. Lots of boilerplate code, adding a pure virtual function in an abstract base class, and override it in every single subclass, so that it returns the type name of the class.
2. Switch to GCC, use the GNU C++ ABI header, and drop support for MSVC.

MadocComadrin

  • Bay Watcher
  • A mysterious laboratory goblin!
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #5158 on: October 29, 2013, 07:11:02 pm »

I'm currently working with some half-finished code which implements a bastardized form of the command pattern. Long story short, I now have to implement a switch over an enum with over 100 cases. I just finished the 'c's.

Arrrrghbhsadsphfpharghupaofh.

Edit: Oh, and I can't even use reflection to pick out the methods that need to be invoked because the enum is set up weirdly.
« Last Edit: October 29, 2013, 07:13:45 pm by MadocComadrin »
Logged

Skyrunner

  • Bay Watcher
  • ?!?!
    • View Profile
    • Portfolio
Re: if self.isCoder(): post() #Programming Thread
« Reply #5159 on: October 29, 2013, 10:05:11 pm »

I did some research - MSVC has a function that can supposedly demangle type names, but apparently it doesn't work unless the type is in the global scope. If it's a nested type or inside of a namespace, it doesn't work.

Unfortunately, it looks like your options are as follows:

1. Lots of boilerplate code, adding a pure virtual function in an abstract base class, and override it in every single subclass, so that it returns the type name of the class.
2. Switch to GCC, use the GNU C++ ABI header, and drop support for MSVC.
I feel that msvs compatibility is worth having clunky code in pplaces. Its debugger is unparallelled.
Logged

bay12 lower boards IRC:irc.darkmyst.org @ #bay12lb
"Oh, they never lie. They dissemble, evade, prevaricate, confoud, confuse, distract, obscure, subtly misrepresent and willfully misunderstand with what often appears to be a positively gleeful relish ... but they never lie" -- Look To Windward
Pages: 1 ... 342 343 [344] 345 346 ... 796