Sign in to follow this  

Downcasting problem - C++

This topic is 3588 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi i'm Sean, first time poster. I have a question regarding a downcasting problem in my code. Everything in the code works correctly, except for this partciular part. else if((int)ch == 13 && (typeid(*(currentmenu->options[currentmenu->GetSelectedIndex()])) == typeid(MenuOption))) { menuStack.Push(currentmenu); currentmenu = GetFullMenu(currentmenu->options[currentmenu->GetSelectedIndex()]. ????????? system("cls"); currentmenu->Show(); cout << "You pressed the enter key.\n"; } The place i have the problem is where the ???'s are. What I am doing is using a function to read data in from a file, and it works fine (fully tested). Since options is a dynamic array of Option's, and MenuOption's (Option's child), i want to access the method of the object at the given index. But when i try to type the . or -> operator, i can't access that object's methods. I'm really stuck with this, and i was thinking it might be a simple dynamic_cast issue, but i can't seem to get it to work. Please help! Note: currentmenu is of class type FullMenu, which contains a dynamicarray called options that holds both Option's (menu selections that haven't been implemented yet) and MenuOption's (menu selections that can be used to open subsequent menus). Here's the class for FullMenu. class FullMenu { public: FullMenu(const char* title = "Unnamed", int SelectedIndex = 0); ~FullMenu(); void SetSelectedIndex(int num); void Show(); char* GetTitle() const; int GetSelectedIndex() const; DynArray<Option*> options; private: int m_nSelectedIndex; char* m_szTitle; };

Share this post


Link to post
Share on other sites
Ok i changed it to

currentmenu = GetFullMenu(dynamic_cast<MenuOption>(currentmenu->options[currentmenu->GetSelectedIndex()]).GetFileName());

So that gets that file for the new menu, generates the menu, and returns it to the currentmenu.

2 errors:

left of ',GetFileName' must have class/struct/union

&

'MenuOption': invalid target type for dynamic_cast

I've been at this for hours...

Share this post


Link to post
Share on other sites
Ok, intellisense is still not picking it up, but now i debugged it down to a point after that line, and it is successfully returning the filename into the function call, so here is my file input function where the new crash is happening.

FullMenu* GetFullMenu(const char* filename)
{
char temp[NUM_SIZE];
string tempstring, tempstring2;
int numoptions = 0, numvalue = 0, iter = 0, quotecount = 0;
FILE * filey = fopen(filename, "r");
fgets(temp, NUM_SIZE, filey);

It's crashing on the

fgets(temp, NUM_SIZE, filey);

When i hover over filename, it has the string, with quotes, for the filename. But now filey is undefined by the time it does fgets. It has no problem the first time i call this function. And i do close the previous file at the end of the function.

Share this post


Link to post
Share on other sites
Ok i added the ferror check as follows:

FullMenu* GetFullMenu(const char* filename)
{
char temp[NUM_SIZE];
string tempstring, tempstring2;
int numoptions = 0, numvalue = 0, iter = 0, quotecount = 0;
FILE * filey = fopen(filename, "r");
if(ferror(filey) != 0)
{
cout << "The file did not open.\n";
}
fgets(temp, NUM_SIZE, filey);

However, not it crashed at the

if(ferror(filey) != 0)

dragging ferror(filey) to the watch window shows

Error: symbol "ferror" not found

but that would make sense, since filey was undefined after the

FILE * filey = fopen(filename, "r");

I'm still confused.... lol

End result: filey is still undefined, and i can't figure out why. It should work...


Oh, the reason i'm using this instead of fstream is because at Full Sail, we are learning code optimization, and including fstream would add a lot of overhead stuff that wouldn't be needed or wanted in a large scale game. And we're building code that we'll use in projects to come, so i wanted to make the most speed-based menu system i could.

Share this post


Link to post
Share on other sites
So you are trying to solve a problem you don't have with code you don't understand, interesting. A quick look at TFM(why doesn't anyone RTFM) reveals that fopen returns null when there is an error when opening the file, and as it is a C function you should include errno.h and use its functions to get a reasonable error message when it fails to open a file.

Share this post


Link to post
Share on other sites
Quote:
Original post by Palidorflame

Oh, the reason i'm using this instead of fstream is because at Full Sail, we are learning code optimization, and including fstream would add a lot of overhead stuff that wouldn't be needed or wanted in a large scale game. And we're building code that we'll use in projects to come, so i wanted to make the most speed-based menu system i could.


This is a bunch of FUD and so wrong on so many levels.

Your code uses std::cout and std::string (apparently), which means that 95% of "overhead" is already in. Including fstream doesn't change much.

Or are we talking code bloat? How much does fstream contribute to that?

Compilation times? There's ios_fwd.

What are the performance characteristics of DynArray?

On any large scale project in C++ you do not want C with classes. You want solidly engineered robust classes that don't crash on every error. And looking into performance of a menu system is completely redundant, especially at this point, especially while learning C with classes, especially before even covering things like polymorphism.

This is exactly the reason why such schools get such bad rep, even if it ultimately isn't always warranted.

Share this post


Link to post
Share on other sites
I apologize if something i comment on about programming is either incorrect, or not efficient. I just started c++ for the first time in November. In my opinion, i'm doing a fairly good job, but I had a small coding problem that i was hoping someone here could help me discover (that's the point of forums, right?).

I will just consult friends and teachers. Thanks for the responses.

Share this post


Link to post
Share on other sites
I don't understand why your design is so complicated.

Why would a "full menu" contain "options" that are not "menu options"? Aren't they menu options by virtue of the fact that they are in a menu? Even then, why would you need to downcast? Is there something that menu options can do that ordinary options can't? If so, why?

Also, why do you have to ask the menu what its "selected index" is, and then ask it again what option corresponds to that index? Why would calling code ever even care that the menu has such a concept as an "index"? Your interface is too complicated; what the calling code wants to know is what option is selected, so that's what the member function should be: getSelectedOption().

Also, why do you have to save the old menu and create a new one in two steps? The "menu stack" can be more intelligent than that. Why would you ever push something and then not create a new menu? Why would you ever create a new menu without remembering the current one? Pairs of actions are algorithms; encapsulate them.

Also, don't convert characters to integers just to figure out what character they are. There are symbolic constants for characters: you just put them in single quotes.

Also, use references to avoid repeating common sub-expressions (often, this is a temporary measure until you can refactor in a better way).

Quote:
Original post by Palidorflame
I apologize if something i comment on about programming is either incorrect, or not efficient. I just started c++ for the first time in November. In my opinion, i'm doing a fairly good job, but I had a small coding problem that i was hoping someone here could help me discover (that's the point of forums, right?).


I won't try to speak for other forums, but the point of our forum is to teach you something. If you are not interested in learning from us, then I suppose I won't very easily convince you otherwise, but I would urge you to reconsider. You don't need to apologize for not knowing something, but you are expected not to assert things without being able to justify them. (Whether or not you are doing a "fairly good job" is (a) dependant on a lot of missing context (previous programming experience?) and (b) largely irrelevant anyway.)

Antheus knows what he's talking about, here. Also, consider that constant overheads are more acceptable in a large project: they get averaged out. Basically the only people who care about <iostream> adding half a meg to the final executable size are the ones who have a ridiculously small executable size as a design requirement (i.e., people in the demo scene).

Share this post


Link to post
Share on other sites
Zahlman,

I looked over my code a few hundred times, and while doing so i looked for some of the things you mentioned that would be better design. I have to admit, i haven't really had a chance to think about design that much, so I've had a hard time creating good objects.

I do see some thing that probably don't even need to be there, such as the Option class altogether, and i'm going to start changing these areas. I do thank you for your insight. I didn't mean to sound rude earlier, but after looking at it, i realized it must have come off that way. So i apologize to all.

I finally did figure out what was wrong, and it was a stupid problem lol When i initialized my currentmenu, i hardcoded the file name, but the entries in my text file were there as inside quotes. So, when it tried to read the file, there were quotes on both sides of the filename. So it did in fact error out, as stonemetal and Antheus said!

Share this post


Link to post
Share on other sites
Quote:
Original post by Palidorflame
I do see some thing that probably don't even need to be there, such as the Option class altogether, and i'm going to start changing these areas. I do thank you for your insight. I didn't mean to sound rude earlier, but after looking at it, i realized it must have come off that way. So i apologize to all.


It happens; don't worry about it. The unspoken policy is

1) Try really hard to make sure you sound like you're criticizing code, and not the person.
2) Try really hard to assume your code is what is being criticized, rather than you.

Quote:
I finally did figure out what was wrong, and it was a stupid problem lol When i initialized my currentmenu, i hardcoded the file name, but the entries in my text file were there as inside quotes. So, when it tried to read the file, there were quotes on both sides of the filename. So it did in fact error out, as stonemetal and Antheus said!


Heh. :) (EDIT: I initially misread your description of the problem.)

Share this post


Link to post
Share on other sites
incidentally on the whole optimizing stuff by dropping back to C style file handling, I really think you are looking in the wrong area. First off the slowest part of file I/O is going to be disk access the difference in speed is like ordering a book from amazon and it gets delivered a year later optimizing the order process so that it takes seconds instead of minutes doesn't even register on the clock. As far as code size goes, IDtech5 supports textures of 5GB in size and games on xbox360 have shipped on three DVDs do you really think dropping a half meg off your executable size really means anything?

If you want to do something that may make a difference download zlib and try compressing your art assets. You still won't get much out of it since most of your textures and what not will already be compressed, but from what I have seen most model formats don't use compression so you will get some benefit out of it. Another thing to try is build a pre-loader so that load times are hidden as much as possible.

Share this post


Link to post
Share on other sites
Quote:
Original post by Palidorflame
...Oh, the reason i'm using this instead of fstream is because at Full Sail, we are learning code optimization, and including fstream would add a lot of overhead stuff that wouldn't be needed or wanted in a large scale game. And we're building code that we'll use in projects to come, so i wanted to make the most speed-based menu system i could.


Apparently, you haven't learned very much about optimization yet.

Rule 1: Profile first.
Rule 2: Optimize the algorithm before the code.

My two favorite optimization (mis)quotes:
"Premature optimization is the root of all evil." -- Donald Knuth
"Optimization without measurement is a waste of time." -- David Joiner

Share this post


Link to post
Share on other sites

This topic is 3588 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this