CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 12 of 12
  1. #1
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    'const' member functions

    Code:
    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

  2. #2
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: 'const' member functions

    Just a guess (never have used GTK): Have you tried this?

    Code:
    	const Glib::RefPtr<const Gdk::Window> p = canvas_event_box.get_window();
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  3. #3
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Re: 'const' member functions

    Addendum...

    I discovered that I can obtain pointer 'p' by moving the position of const - i.e. this doesn't compile...

    Code:
    void functionB() const
    {
    	const Glib::RefPtr<Gdk::Window> p = canvas_event_box.get_window();
    }
    but this does compile...

    Code:
    void functionB() const
    {
    	Glib::RefPtr<const Gdk::Window> p = canvas_event_box.get_window();
    }
    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

    error C2662: 'Gdk::Window::get_pointer' : cannot convert 'this' pointer from 'const Gdk::Window' to 'Gdk::Window &'
    1> Conversion loses qualifiers
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  4. #4
    Join Date
    Apr 1999
    Posts
    27,449

    Re: 'const' member functions

    Which line is line 199?
    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.

    Regards,

    Paul McKenzie

  5. #5
    Join Date
    Apr 1999
    Posts
    27,449

    Re: 'const' member functions

    Quote Originally Posted by John E View Post
    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.

    Regards,

    Paul McKenzie

  6. #6
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Re: 'const' member functions

    Gdk::Window::get_pointer() is declared like this:-

    Code:
     Glib::RefPtr<Window> get_pointer(int& x, int& y, ModifierType& mask);
    Fortunately I'm building from source so I can easily add an overrided version like so:-

    Code:
     Glib::RefPtr<Window> get_pointer(int& x, int& y, ModifierType& mask) const;
    Before I do that though... isn't there any way that const_cast could come to my aid here?
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  7. #7
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Re: 'const' member functions

    Quote Originally Posted by John E View Post
    Before I do that though... isn't there any way that const_cast could come to my aid here?
    I might have answered my own question... this seems to do the trick (at least it compiles. anyway)

    Code:
    void Editor::functionB() const
    {
    gint x, y;
    Gdk::ModifierType state;
    
    	Glib::RefPtr<Gdk::Window> p = const_cast<Editor*>(this)->track_canvas_event_box.get_window();
    	p->get_pointer (x, y, state);
    }
    Last edited by John E; January 24th, 2013 at 07:33 AM.
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  8. #8
    Join Date
    Apr 1999
    Posts
    27,449

    Re: 'const' member functions

    Quote Originally Posted by John E View Post
    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.

    Regards,

    Paul McKenzie

  9. #9
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Re: 'const' member functions

    Good point. I wouldn't have thought of that....

    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

  10. #10
    Join Date
    Apr 1999
    Posts
    27,449

    Re: 'const' member functions

    Quote Originally Posted by John E View Post
    Good point. I wouldn't have thought of that....

    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.

    Regards,

    Paul McKenzie

  11. #11
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Re: 'const' member functions

    Quote Originally Posted by Paul McKenzie View Post
    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 04:16 PM.
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  12. #12
    Join Date
    Apr 1999
    Posts
    27,449

    Re: 'const' member functions

    Quote Originally Posted by John E View Post
    Thanks. I tried that a little earlier and it compiled OK. However, it would give me a non-standard API
    Is it the one where you're passing a temporary object to a function that expects the parameter to be non-const?

    If so, that actually is an error in C++ proper -- it's just that Visual C++ considers it only a warning (assuming you set the warning level to 4)

    Regards,

    Paul McKenzie

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured