Putting the 'role' back in role-playing games since 2002.
Donate to Codex
Good Old Games
  • Welcome to rpgcodex.net, a site dedicated to discussing computer based role-playing games in a free and open fashion. We're less strict than other forums, but please refer to the rules.

    "This message is awaiting moderator approval": All new users must pass through our moderation queue before they will be able to post normally. Until your account has "passed" your posts will only be visible to yourself (and moderators) until they are approved. Give us a week to get around to approving / deleting / ignoring your mundane opinion on crap before hassling us about it. Once you have passed the moderation period (think of it as a test), you will be able to post normally, just like all the other retards.

I need a way to put all my objects inside the same container.

desocupado

Magister
Joined
Nov 17, 2008
Messages
1,802
I've got a vector<Base_PC*> PC_List.

I'm putting inside this vector, pointers to objects of 2 classes derived from Base_PC. Fighter and Fire_Mage.

What I'm trying to do, I'm trying to have all my objects inside the same container, in this case, pointers to all my objects inside the same container.

The pointers to Fighter and Fire_Mage enter the container no problem, and using methods that were written in Base_PC, or that are virtual//pure virtual work fine.

However, when I call a method exclusive to Fighter (Fire_Mage is yet to have exclusive methods) like this:

(*point_PC_List)[index]->method(); //(The (*foo) is because I don't pass the vector itself, I pass a pointer)

The compiler shits itself and bitches about how I can't do that and how shitty a programmer I am.

I don't know how to solve this. I really would like to keep all my objects (or pointers to my objects) inside the same container because fuck me I already wrote a fuckton of code based on having all my objects(or pointers to my objects) inside the same container.

Any help you guys can give me?
 

Norfleet

Moderator
Joined
Jun 3, 2005
Messages
12,250
This is C++ or something similar? You need to do a construction like ((Fighter *)blahblahblah)->method().

I'm assuming that you're already verified the object you're dealing with is, in fact, a fighter, or bad things happen.
 

desocupado

Magister
Joined
Nov 17, 2008
Messages
1,802
Sorry, I always forget to mention

It's C++.

The compiler ain't complaining it doesn't know what the line is. It's complaining that that object inside that vector is a Base_PC, and that I'm trying funny stuff with it's inner parts. And by that I mean invoking Fighter's methods that shouldn't be there if it's a Base_PC pointer, which it isn't, but the container says Base_PC.

I looked it up, I think what I'm doing is an implicit downcasting or something, which doesn't work (nor should).

Here's the actual compiling error.

1>c:\documents and settings\daniel\my documents\visual studio 2010\projects\projeto\projeto\pc_actions.cpp(53): error C2039: 'Draw_SI' : is not a member of 'Base_PC'

Draw_SI is a method from the Fighter class which is not present on Base_PC.

This here is me pushing Fighter*s into a Base_PC vector. Lo, and behold! Men of little faith!

std::vector<Base_PC*> PC_List;
Fighter fighter1(41);
Fighter* p_fighter1 = &fighter1;
PC_List.push_back(p_fighter1);
 

Norfleet

Moderator
Joined
Jun 3, 2005
Messages
12,250
Yes, so it's what I said. You can put fighter into a Base_PC because a Fighter is a valid base_PC, but you can't call Fighter-specific methods on an item extracted from a Base_PC list, which has been reduced to its lowest common denominator.

Instead, you must first, verify in code that what you're dealing with is actually a fighter (horrible explosion if your Base_PC is a Thief or something), and then, as I mentioned previously, cast it back into a fighter before invoking it:

((Fighter *)((*point_PC_List)[index]))->method();
 

Derek Larp

Cipher
Joined
Jul 25, 2008
Messages
423
Why don't you put the exclusive methods as virtual methods in the Base_PC and have them do jack shit or return an error there, and have them do what you want them to do in your derived class.

Like here: http://www.cplusplus.com/doc/tutorial/polymorphism/ with the area of the polygons.

I used the same system for inventory objects in a roguelike engine test thing I did a while back, so the inventory would be just one vector.
It wasn't pretty, but it worked.
 

desocupado

Magister
Joined
Nov 17, 2008
Messages
1,802
Why don't you put the exclusive methods as virtual methods in the Base_PC and have them do jack shit or return an error there, and have them do what you want them to do in your derived class.

Like here: http://www.cplusplus.com/doc/tutorial/polymorphism/ with the area of the polygons.

I used the same system for inventory objects in a roguelike engine test thing I did a while back, so the inventory would be just one vector.
It wasn't pretty, but it worked.

I tried something like that, I added all methods of fighter to Base_PC and made them all pure virtual, but then, the compiler complained that Fire_Mage didn't have the pure virtual methods.

I guess it would work in case the methods weren't pure virtual, just virtual, like you're saying.
 

Norfleet

Moderator
Joined
Jun 3, 2005
Messages
12,250
Virtual methods would work. If you make them pure virtual, then you have to implement them on each derived class separately. Since you didn't bother to implement them on your Fire_Mage class, the compiler bitches. You could make them non-pure-virtual, where the base version either does something really basic and low-level, or nothing at all.

But if you just want to clumsily kludge your way around the issue or have something very specific in mind, see what I wrote previously.
 

Alex

Arcane
Joined
Jun 14, 2007
Messages
8,754
Location
São Paulo - Brasil
there are two ways, the straight forward but not scalable /instanceof + casts
and the boring and full of code but typesafe /goddamned visitor-double-dispatch trick

There are actually 3 ways, but the best (multimethods) is not available in C (or java, or XXXX, except python as far as i can tell)

http://stackoverflow.com/questions/9818132/difference-betwen-visitor-pattern-double-dispatch

I think this is a bit of overkill, SCO! Deso is just a bit lost about how to use objects cast dynamically in C++, rather than the static casting it uses by default. And in the end, it is either pointers or references, and references are a bad idea here, after all, because you want to change the array's contents without changing the object represented in them. For example, even if the game's party was a 6 position array, if the 5th member left and another joined instead, you wouldn't have changed the party composition, you would have transformed one member into the other! Which is really unfortunate, because pointer interface is so clunky, but there isn't much you can do. Sorry, desocupado.
 

snoek

Cipher
Joined
May 5, 2003
Messages
1,125
Location
Belgium, bro
you could add an additional field, an enum or a string or whatever which identifies what kind of object it is and then make a Fire_Mage or Fighter pointer & call yo' class specific methods
 

Ion Prothon II

Liturgist
Joined
Jan 10, 2012
Messages
1,011
Location
Ołobok Zdrój
Then he could as well completely get rid of inheritance and polymorphism, and replace it with function pointers and map<string, void*>.

Not that it wouldn't be better than separate C++ classes for (lol!) in- game characters.

:troll:
 

toro

Arcane
Vatnik
Joined
Apr 14, 2009
Messages
14,123
void* is C stuff. using it in a c++ project is a good indicator of bad design.

desocupado: virtual base class is what you need.

however virtual methods are incurring run-time penalties (additional v-table) and design penalties.

the proper solution is to favor composition instead of inheritance.
 

SCO

Arcane
In My Safe Space
Joined
Feb 3, 2009
Messages
16,320
Shadorwun: Hong Kong
Did you know Stroustrup 'considered' multiple-dispatch but 'couldn't find a way to do it efficiently'

:troll:
 

Ion Prothon II

Liturgist
Joined
Jan 10, 2012
Messages
1,011
Location
Ołobok Zdrój
void* is C stuff. using it in a c++ project is a good indicator of bad design.

desocupado: virtual base class is what you need.

however virtual methods are incurring run-time penalties (additional v-table) and design penalties.

the proper solution is to favor composition instead of inheritance.


void* is the only C / C++ equivalent of object / anytype. There are things you cannot do with templates or base class pointers, and weak- minded C++ purism ain't gonna help you there.
...
And yet it's C++ and you're writing:
the proper solution is to favor composition instead of inheritance.
Because composition isn't bashed in C++ awesome courses with gorgeous class diagrams as a filthy C solution. :?
and:
virtual methods are incurring run-time penalties (additional v-table)

C++, VTable and performance penalty: :deadhorse: since decades.

It's year 2021, but hey, it causes a laughable penalty to performance, be careful with this shit.

design penalties.
Huh?
 

toro

Arcane
Vatnik
Joined
Apr 14, 2009
Messages
14,123
void* is C stuff. using it in a c++ project is a good indicator of bad design.

desocupado: virtual base class is what you need.

however virtual methods are incurring run-time penalties (additional v-table) and design penalties.

the proper solution is to favor composition instead of inheritance.


void* is the only C / C++ equivalent of object / anytype. There are things you cannot do with templates or base class pointers, and weak- minded C++ purism ain't gonna help you there.
...
And yet it's C++ and you're writing:
the proper solution is to favor composition instead of inheritance.
Because composition isn't bashed in C++ awesome courses with gorgeous class diagrams as a filthy C solution. :?
and:
virtual methods are incurring run-time penalties (additional v-table)

C++, VTable and performance penalty: :deadhorse: since decades.

It's year 2021, but hey, it causes a laughable penalty to performance, be careful with this shit.

design penalties.
Huh?

1. void* is a big no-no for frameworks. If you ever worked with a C library using void* as parameters, you would know why.
Indeed, there are cases in which is unavoidable. But using it denotes an inconsistency in the design.

2. And you comment about C++ purism is lame. If you want to learn a language and use it properly, it's better to use the correct syntax and learn about the actual differences between C and C++. It's just my opinion.

3. I did not understand you comment about composition.

4. Even today in embedded systems is important to have optimized code. And there is definitely a runtime penalty when all objects in the game are derived from one or more classes.

My comments are not wrong, however is true that thanks to my job I'm more inclined to write optimized code and look for such things. It's just my opinion.
 

desocupado

Magister
Joined
Nov 17, 2008
Messages
1,802
Uh, guys, I already solved this issue. To be honest, some code restructuration I did, did away with the need for that, but I learned some stuff from this thread, so it was not a waste.

Anyway, I need a tip. I've been using Visual Studio 2010, but I can't still figure out how to tell where my resources are. When I compile my program, the program crashes, and I have to go to the debug folder, and run the program from there. And then it runs. The problem is, I put the necessary files inside the debug folder (images and a font), but the dumb compiler doesn't run the program from there. How do I solve that?

Also, should I even be using Visual Studio 2010? I don't know what half 90% of the options do, I just use it to compile my code, and receive error messages to track my bugs. Oh, and keep the files neatly organized using the filters.

What's a more friendly IDE? Such a thing even exists?
 

No soup for you!

Guest
Anyway, I need a tip. I've been using Visual Studio 2010, but I can't still figure out how to tell where my resources are. When I compile my program, the program crashes, and I have to go to the debug folder, and run the program from there. And then it runs. The problem is, I put the necessary files inside the debug folder (images and a font), but the dumb compiler doesn't run the program from there. How do I solve that?

You need to set your Working Directory. Go to the property page for your executable project, in the Debugging subsection, and enter "$(OutDir)" for the "Working Directory" row. That will inform the debugger to launch the executable from the proper directory.
 

desocupado

Magister
Joined
Nov 17, 2008
Messages
1,802
Anyway, I need a tip. I've been using Visual Studio 2010, but I can't still figure out how to tell where my resources are. When I compile my program, the program crashes, and I have to go to the debug folder, and run the program from there. And then it runs. The problem is, I put the necessary files inside the debug folder (images and a font), but the dumb compiler doesn't run the program from there. How do I solve that?

You need to set your Working Directory. Go to the property page for your executable project, in the Debugging subsection, and enter "$(OutDir)" for the "Working Directory" row. That will inform the debugger to launch the executable from the proper directory.

Well, thank you very much, that worked fine. I searched the net once or twice over this, but couldn't find the right wording so that google would give me relevant results.
 

GordonHalfman

Scholar
Joined
Nov 5, 2011
Messages
119
Every code base I've worked on has ended up having to just down cast at some point using some type checking system or other. Since it's usually the case that virtual methods aren't enough. This kind of thing doesn't seem to cause many problems in practice, but is often seen as an indicator of bad design. Which I think probably applies in this case, I'm almost sure that having a separate C++ class for in game classes is a bad idea. What if you want to add multi-classing for example?
 

desocupado

Magister
Joined
Nov 17, 2008
Messages
1,802
Every code base I've worked on has ended up having to just down cast at some point using some type checking system or other. Since it's usually the case that virtual methods aren't enough. This kind of thing doesn't seem to cause many problems in practice, but is often seen as an indicator of bad design. Which I think probably applies in this case, I'm almost sure that having a separate C++ class for in game classes is a bad idea. What if you want to add multi-classing for example?

Well, right now, in my code, everything is in the superclass, and there's only 2 methods on the Fighter class, that also could be on the superclass.

The Fire_Mage however has a redefined Attack method

I think I can handle multi-classing despite of the individualization, however, it's not planned.
 

Ion Prothon II

Liturgist
Joined
Jan 10, 2012
Messages
1,011
Location
Ołobok Zdrój
toro:

C++ is a clusterfuck. It's a hybridal language, mixing paradigmates, syntax and extremely low- level features with high- level ones. The hate towards C++ is completely justified. Any talk about 'C++ purism' makes me smile. It's an artificial approach and depends heavily on the politics of a project.
Measuring a profficiency in programming language, by the ability to apply an ideology instead of solving problems in the most efficient way meeting the requirements, is retarded. But it's an obvious truism, I believe.

Anytype is unavoidable, when you need a container for heterogenous data or want to work with data of unspecified type. It's also very helpful in implementing a far- reaching flexibility, constrained properly by a documentation: like framework, plugin architecture, etc.
In C++ there's no other alternative, unless you're using a high- level framework, like Boost or Qt. Still, I think the generic type from those has only a minor advantage over void*, in terms of type safety. C++ is unable to store and utilize the type information a Java or C# does.

Any discussion about the two things above, in general terms, without refering to a specific problem, is worthless like a drunken talk about philisophy. It also leads to an unevitable:
'I've been writing business applications / graduation projects / whatever since 20 years, I got a ponytail reaching the ground, and I've never needed X, it's an inconsistency of design'.
Besides, methodology and logic of enterprise level programming doesn't necessary apply to small or tiny projects, especially games.

My comment on composition was a joke that appearently failed. I've seen C++ courses, where the authors, despite being rational people, went so far with their purism and object paradigm, they claimed composition is a bad trait derived from C and inheritance should be preferred universally over it... and it's an amazingly popular belief IRL.
And talk about composition over inheritance as proper solution in OP's case is too far- fetched. Objects of game world as class structure using extensively polymorphism etc, is good as anything else, if done properly.
The major drawback is rigidness, game- related things hardcoded into other program parts. As for me, it's one of the programming traits I sincerely hate.

As for virtual methods, it's good to know they're inefficient in programming fo embedded systems. It would be really helpful if the thread was about writing software for space sattelites, dvd players and vibrators- instead of PC and mobiles as it likely is.
The performance loss is in fact not a problem, since the CPUs got more than those ~100mhz and 1 level of cache.
Even if runtime penalty was significant (it doesn't), then think how much performance on modern hardware could you lose in a game, with truly prosperous code (class structure, not some dumbfuck algorithms etc) without any compiler optimization. 2 FPS? 5 FPS?
I am not an apologist of poorly written code because heheh CPU is so fast nobody notices, but want to point out the runtime penalty problem insinsignificant now; it's an academic problem analysed when it's needed to test a compiler, not a performance problem for user.

What are 'design penalties' of virtual methods, again?

And in the end, it's good you mentioned your programming- related work and experience. Now everything you write looks smarter and more trustworthy, even I must admit it. Personally I don't see any need for stating such things.

(seriously, I have nothing better to do now :lol: )
 

desocupado

Magister
Joined
Nov 17, 2008
Messages
1,802
I'm confused here (by a lot of things), when you mean "prosperous" code, you mean proper code, or code that seems to be made by prosper?
 

As an Amazon Associate, rpgcodex.net earns from qualifying purchases.
Back
Top Bottom