class Editor
{
// c'tors etc
Gtk::EventBox canvas_event_box;
void functionA();
void functionB() const;
}
// This is fine
void functionA()
{
const Glib::RefPtr<Gdk::Window> p = canvas_event_box.get_window();
}
// But this won't compile
void functionB() const
{
const Glib::RefPtr<Gdk::Window> p = canvas_event_box.get_window();
}
When I try to compile functionB in Visual C++ it gives me this error:-
glibmm/refptr.h(199) : error C2440: 'initializing' : cannot convert from 'const Gdk::Window *' to 'Gdk::Window *'
Conversion loses qualifiers
and this is the code from glibmm/refptr.h
Code:
// The templated ctor allows copy construction from any object that's
// castable. Thus, it does downcasts:
// base_ref = derived_ref
template <class T_CppObject>
template <class T_CastFrom>
inline
RefPtr<T_CppObject>::RefPtr(const RefPtr<T_CastFrom>& src)
:
// A different RefPtr<> will not allow us access to pCppObject_. We need
// to add a get_underlying() for this, but that would encourage incorrect
// use, so we use the less well-known operator->() accessor:
pCppObject_ (src.operator->())
{
if(pCppObject_)
pCppObject_->reference();
}
I don't actually want to change anything in the member variable canvas_event_box. I just want to be able to call one of its functions from my 'const' member function. Is there any syntax I can use to tell VC++ that I'm not actually changing the variable - just using it
"A problem well stated is a problem half solved.” - Charles F. Kettering
The problem now is that having succesfully obtained the pointer, I can't use it !!!
My ultimate aim is to find the 'x' and 'y' co-ordinates for this window's mouse pointer:-
Code:
void functionB() const
{
gint x, y;
Gdk::ModifierType state;
Glib::RefPtr<const Gdk::Window> p = canvas_event_box.get_window();
p->get_pointer (x, y, state);
}
But the red line now gives me this error
If get_pointer() is non-const, then again, you're trying to call a non-const member function on a const object. That isn't going to work.
You need to go through the public interface of whatever Gdk::Window is, and identify which functions are const, which are non-const, and use the appropriate function.
I might have answered my own question... this seems to do the trick (at least it compiles. anyway)
What does the implementation of get_pointer() look like? If it mutates the member variable in any way, then issuing a const_cast is dangerous if you're really calling a non-const function.
Why would the authors of get_pointer() make it non-const? Is it because they were lazy, didn't do their due diligence in making the function const, or for legitimate reasons?
You need to answer that question before using const_cast.
I don't actually want to change anything in the member variable canvas_event_box
Don't use functions that imply that you do want to change the value. If a function is non-const, and you decide to use that function on a non-mutable variable, then nothing is going to fix that except to redesign your code.
It looks reasonably safe (I think). It just wraps a standard 'C' function (which returns a GdkWindow*). That's then used to create a Glib::RefPtr which gets returned to the caller.
Code:
Glib::RefPtr<Window> Window::get_pointer(int& x, int& y, ModifierType& mask)
{
Glib::RefPtr<Window> retvalue = Glib::wrap((GdkWindowObject*)(gdk_window_get_pointer(gobj(), &x, &y, ((GdkModifierType*) &(mask)))));
if(retvalue)
retvalue->reference(); //The function does not do a ref for us.
return retvalue;
}
BTW 'Window' is in the namespace Gdk - so the type of pointer is Glib::RefPtr<Gdk::Window>
"A problem well stated is a problem half solved.” - Charles F. Kettering
It looks reasonably safe (I think). It just wraps a standard 'C' function (which returns a GdkWindow*). That's then used to create a Glib::RefPtr which gets returned to the caller.
You can create a duplication function, stick the const keyword at the end of it, call it in your main function, and compile.
If the compiler doesn't like it, you'll know what in there can be potentially dangerous.
You can create a duplication function, stick the const keyword at the end of it, call it in your main function, and compile.
If the compiler doesn't like it, you'll know what in there can be potentially dangerous.
Thanks. I tried that a little earlier and it compiled OK. However, it would give me a non-standard API - which isn't a massive problem and I'd probably do it that way if there was any danger but for the moment, I think I'd prefer to stick with the const_cast fix. Thanks for all your help Paul.
Last edited by John E; January 24th, 2013 at 03:16 PM.
"A problem well stated is a problem half solved.” - Charles F. Kettering
Bookmarks