What am I doing wrong with this pointer?

I create a GUI class for C ++ and deal with pointers a lot. Call example:

mainGui.activeWindow->activeWidget->init(); 

My problem is that I want to use the activeWidget pointer for another type. activeWidget is of type GUI_BASE. Derived from BASE, I have other classes such as GUI_BUTTON and GUI_TEXTBOX. I want to highlight the activeWidget pointer from GUI_BASE to GUI_TEXTBOX. I assume it will look something like this:

 (GUI_TEXTBOX*)(mainGui.activeWindow->activeWidget)->function(); 

This does not work because the compiler still considers the pointer to be of type GUI_BASE. However, the following bit of code works:

 GUI_TEXTBOX *textbox_pointer; textbox_pointer = (GUI_TEXTBOX*)mainGui.activeWindow->activeWidget; textbox_pointer->function(); 

I hope my problem here is just a syntax problem. Thanks for the help:)

+3
source share
9 answers

The problem is that the cast has a lower priority than that of the cast. → () []. You will need to use the C ++ style or add additional parentheses:

 ((GUI_TEXTBOX*)mainGui.activeWindow->activeWidget)->function(); // Extra parentheses dynamic_cast<GUI_TEXTBOX*>(mainGui.activeWindow->activeWidget)->function(); // C++ style cast 
+18
source

You should not use C-style.

You need to use dynamic C ++ conversion. This will allow you to verify that the object is actually GUI_TEXTBOX before you call the method on it.

 GUI_TEXTBOX* textboxPointer = dynamic_cast<GUI_TEXTBOX*>(mainGui.activeWindow->activeWidget); if (textboxPointer) { // If activeWidget is not a text box then dynamic_cast // will return a NULL. textboxPointer->textBoxMethod(); } // or dynamic_cast<GUI_TEXTBOX&>(*mainGui.activeWindow->activeWidget).textBoxMethod(); // This will throw bad_cast if the activeWidget is not a GUI_TEXTBOX 

Please note that the C-style and reinterpret_cast <> () are not guaranteed to work in this situation (although for most compilers they will be [but this is just an implementation aspect and you will be lucky]). All bets are disabled if the object assigned by activeWidget actually uses multiple inheritance, in this situation you will see strange errors with most compilers if you do not use dynamic_cast <> ().

+9
source

You just need more brackets:

 ((GUI_TEXTBOX*)(mainGui.activeWindow->activeWidget))->function(); 

Actually, this would also work:

 ((GUI_TEXTBOX*)mainGui.activeWindow->activeWidget)->function(); 
+4
source

As others noted:

 ((GUI_TEXTBOX*)(mainGui.activeWindow->activeWidget))->function(); 

The reason is that the -> operator has a higher priority than the casting type.


I will put another plugin for the Steve Oualline rule from "Practical C":

There are 15 priority rules in C (& &? :). A practical programmer reduces these two:

1) Multiplication and division come before addition and subtraction.

2) Put parentheses around everything else.


One final note: downcasts can be dangerous, see Martin York's answer for information on using dynamic_cast<> for safe execution.

+3
source

This is a matter of order of operators (operator priority). Consider the code you tried to make that didn't work:

(GUI_TEXTBOX *) (mainGui.activeWindow-> activeWidget) → function ();

Here the operator -> has a higher priority than your cast. This is why your other code sample works. In another example, you explicitly throw the first one and then call the function. To make it more streamlined, add another set of brackets so that the code looks like this:

((GUI_TEXTBOX *) (mainGui.activeWindow-> activeWidget)) → function ();

+1
source

There are two strategies. One of them is "not working fast": if you applied the wrong type, then you will have an exception, so you will immediately notice that you produced the wrong type. Another “fast-running” option: destination type checking is not performed. This cast should be used only if you know that you cannot be mistaken, or if you do not have a polymorphic type with a base or derivative. I recommend the following depending on your needs (remember to save const when clicked):

 dynamic_cast<GUI_TEXTBOX&>(*mainGui.activeWindow->activeWidget).function(); 

Fail fast : throws std::bad_cast if you produce the wrong type.

 static_cast<GUI_TEXTBOX*>(mainGui.activeWindow->activeWidget)->function(); 

Run fast : does not perform a run-time check. So it will not fail. Rather, it will lead to undefined behavior if you use the wrong type. Caution!

+1
source
 ((GUI_TEXTBOX*)(mainGui.activeWindow->activeWidget))->function(); 
0
source

-> has a higher priority than (cast), so access to the member is performed before the broadcast. See here for operator priority: http://www.cppreference.com/wiki/operator_precedence

As stated above, you need more parentheses.

0
source
 if( GUI_TEXTBOX* ptr = dynamic_cast<GUI_TEXTBOX *>(mainGui.activeWindow->activeWidget) ) { ptr->function(); } 

The reason you want to do this is because the pointer you are trying to execute may not actually point to the GUI_TEXTBOX object, and you want to make sure that it does this before calling the text field methods on it. For this you need a C ++ dynamic cast.

0
source

All Articles