Thread: error 2662: can not convert 'this' pointer from .. to ...

  1. #1
    Registered User
    Join Date
    Mar 2009
    Posts
    10

    error 2662: can not convert 'this' pointer from .. to ...

    Hello there,

    I'm creating kind of a GUI system, and I found myself in trouble when inheriting my base class in my other classes.

    This is the gui header:
    Code:
    #ifndef _GUI_H
    #define _GUI_H
    
    #define WIN32_MEAN_AND_LEAN
    #include <windows.h>
    #include <vector>
    #include <string>
    
    #define GUI_VERSION 1.0.0.1
    
    #define TRUE 1
    #define FALSE 0
    
    #define STRUE "true"
    #define SFALSE "false"
    
    #define PGET(p) get_##p()
    #define PSET(p,v) set_##p(v)
    
    // Property related
    #define DECLARE_PROPERTY(p,t)	t get_##p(); \
    								void set_##p(t);
    #define DECLARE_RO_PROPERTY(p,t) t get_##p();
    #define DECLARE_WO_PROPERTY(p,t) void set_##p(t);
    
    // Number to bool
    #define NTOB(n) (n>0)? TRUE : FALSE;
    
    namespace GUI{
    
    	struct COORD_S{
    		int x;
    		int y;
    		COORD_S(int _x, int _y)
    		{
    			this->x = _x;
    			this->y = _y;
    		}
    		COORD_S()
    		{
    			COORD_S(0,0);
    		}
    		COORD_S& operator=(const COORD_S& c)
    		{
    			if(this == &c) return *this;
    			this->x = c.x;
    			this->y = c.y;
    			return *this;
    		}
    		COORD_S& operator+(const COORD_S& c)
    		{
    			if(this == &c) return *this;
    			this->x += c.x;
    			this->y += c.y;
    			return *this;
    		}
    		COORD_S& operator+(const int i)
    		{
    			this->x += i;
    			this->y += i;
    			return *this;
    		}
    		COORD_S& operator-(const COORD_S& c)
    		{
    			if(this == &c) return *this;
    			this->x -= c.x;
    			this->y -= c.y;
    			return *this;
    		}
    		COORD_S& operator-(const int i)
    		{
    			this->x -= i;
    			this->y -= i;
    			return *this;
    		}
    		COORD_S& operator*(const COORD_S& c)
    		{
    			if(this == &c) return *this;
    			this->x = this->x*c.x;
    			this->y = this->y*c.y;
    			return *this;
    		}
    		COORD_S& operator*(const int i)
    		{
    			this->x = this->x*i;
    			this->y = this->y*i;
    			return *this;
    		}
    		bool operator==(const COORD_S& c)
    		{
    			if(this == &c) return true;
    			return ((this->x == c.x) && (this->y = c.y));
    		}
    	};
    	struct SIZE_S{
    		int width;
    		int height;
    		SIZE_S(int _w, int _h)
    		{
    			this->width = _w;
    			this->height = _h;
    		}
    		SIZE_S()
    		{
    			SIZE_S(0,0);
    		}
    		SIZE_S& operator=(const SIZE_S& c)
    		{
    			if(this == &c) return *this;
    			this->width = c.width;
    			this->height = c.height;
    			return *this;
    		}
    		SIZE_S& operator+(const SIZE_S& c)
    		{
    			if(this == &c) return *this;
    			this->width += c.width;
    			this->height += c.height;
    			return *this;
    		}
    		SIZE_S& operator+(const int i)
    		{
    			this->width += i;
    			this->height += i;
    			return *this;
    		}
    		SIZE_S& operator-(const SIZE_S& c)
    		{
    			if(this == &c) return *this;
    			this->width -= c.width;
    			this->height -= c.height;
    			return *this;
    		}
    		SIZE_S& operator-(const int i)
    		{
    			this->width -= i;
    			this->height -= i;
    			return *this;
    		}
    		SIZE_S& operator*(const SIZE_S& c)
    		{
    			if(this == &c) return *this;
    			this->width = this->width*c.width;
    			this->height = this->height*c.height;
    			return *this;
    		}
    		SIZE_S& operator*(const int i)
    		{
    			this->width = this->width*i;
    			this->height = this->height*i;
    			return *this;
    		}
    		bool operator==(const SIZE_S& c)
    		{
    			if(this == &c) return true;
    			return ((this->width == c.width) && (this->height = c.height));
    		}
    	};
    
    	// Events
    	enum Events{
    		EVENT_NULL		= (0<<0),
    		EVENT_MOUSE		= (1<<0),
    		EVENT_KEYBD		= (1<<1)
    	};
    	// Mouse events
    	enum MouseEvents{
    		MOUSE_NULL			= (0<<0),
    		MOUSE_MOVE			= (1<<0),
    		MOUSE_DOWN			= (1<<1),
    		MOUSE_UP			= (1<<2),
    		MOUSE_MBUTTON1		= (1<<3),
    		MOUSE_MBUTTON2		= (1<<4),
    		MOUSE_MBUTTON3		= (1<<5),
    		MOUSE_SCROLLUP		= (1<<6),
    		MOUSE_SCROLLDOWN	= (1<<7)
    	};
    	// Keyboard events
    	enum KeybdEvents{
    		KEYBD_NULL		= (0<<0),
    		KEYDB_KEYDOWN	= (1<<0),
    		KEYBD_KEYUP		= (1<<1)
    	};
    	enum{
    	};
    
    };
    
    #endif
    This is the header of my base class:
    Code:
    #ifndef _OBJECT_H
    #define _OBJECT_H
    
    #include "gui.h"
    
    namespace GUI{
    
    	class CObject{
    	public:
    		CObject();
    		CObject(const CObject&);
    		virtual ~CObject();
    		CObject& operator=(const CObject&);
    		const CObject& operator=(const CObject&) const;
    		DECLARE_PROPERTY(name,std::string);
    	protected:
    	private:
    		std::string sName;
    	};
    };
    
    #endif
    This is the code of the inheriting class:
    Code:
    #ifndef _CONTROL_H
    #define _CONTROL_H
    
    #include "gui.h"
    #include "object.h"
    
    namespace GUI{
    
    	class CControl : public CObject{
    	public:
    		CControl();
    		CControl(const CControl&);
    		virtual ~CControl();
    		CControl& operator=(const CControl&);
    		const CControl& operator=(const CControl&) const;
    		virtual LRESULT _WndProc(HWND, UINT, WPARAM, LPARAM);
    		DECLARE_PROPERTY(parent,CControl*);
    		DECLARE_RO_PROPERTY(hwnd,HWND);
    	protected:
    		static LRESULT CALLBACK WndProc( HWND , UINT , WPARAM , LPARAM );
    	private:
    		HWND m_hWnd;
    		CControl *m_parent;
    	};
    
    };
    
    #endif
    The errors I get are the following:
    - when trying to get/set the name of the object using the get_name/set_name functions, the compiler gives me the following error:
    Code:
    error C2662: 'GUI::CObject::get_name' : cannot convert 'this' pointer from 'const GUI::CControl' to 'GUI::CObject &'
    - when trying to get/set the hwnd or parent of a control, i get the following error:
    Code:
    error C2662: 'GUI::CControl::get_hwnd' : cannot convert 'this' pointer from 'const GUI::CControl' to 'GUI::CControl &'
    Anyone knows what is going on here?

    Grtz, Tom.

  2. #2
    The larch
    Join Date
    May 2006
    Posts
    3,573
    It would help if you provided code that actually produces these errors.

    One thing to note is that your getters are not const correct. (The error messages seem to say that this is const where you are using it, and you are trying to use it to call non-const getters.)

    (Using macros to create getters and setters seems a bit of an abomination. Clearly you need to type more to use DECLARE_RO_PROPERTY and DECLARE_WO_PROPERTY that just typing the declaration yourself?)
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    These errors occur when you call a non-const function from a const function (or const object).
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #4
    Registered User
    Join Date
    Mar 2009
    Posts
    10
    Quote Originally Posted by anon View Post
    It would help if you provided code that actually produces these errors.

    One thing to note is that your getters are not const correct. (The error messages seem to say that this is const where you are using it, and you are trying to use it to call non-const getters.)

    (Using macros to create getters and setters seems a bit of an abomination. Clearly you need to type more to use DECLARE_RO_PROPERTY and DECLARE_WO_PROPERTY that just typing the declaration yourself?)

    Yes anon I realized that, so now I wrote kind of a Property class to get the same result.

    This is the property H file:
    PHP Code:
    #ifndef _PROPERTY_H
    #define _PROPERTY_H

    #define READACCESS(m)    (((m&PROP_READ) == PROP_READ)? true : false)
    #define WRITEACCESS(m)    (((m&PROP_READ) == PROP_READ)? true : false)

    enum PROPERTY_ACCESS_MODE{
        
    PROP_NULL         = (0<<0),
        
    PROP_READ         = (1<<0),
        
    PROP_WRITE         = (1<<1),
        
    PROP_READWRITE     PROP_READ|PROP_WRITE
    };

    namespace 
    GUI{

        
    template<class C, class TPROPERTY_ACCESS_MODE mode PROP_READWRITE> class CProperty{
        public:
            
    typedef void(C::*write_callback)(T);
            
    typedef T(C::*read_callback)(void);
            
    CProperty();
            
    CProperty(T);
            
    CProperty(const CProperty&);
            ~
    CProperty();
            
    void owner(C*);
            
    void RegisterReadCallback(read_callback);
            
    void RegisterWriteCallback(write_callback);
            
    T operator = (const Tv);
            
    operator T();
        protected:
        private:
            
    PROPERTY_ACCESS_MODE m_mode;
            
    Cm_class;
            
    read_callback m_read_callback;
            
    write_callback m_write_callback;
        };
    };

    #endif 
    This is the property CPP file:
    PHP Code:
    #include "property.h"
    #include <cassert>

    using namespace GUI;

    template<class C, class T,PROPERTY_ACCESS_MODE mCProperty<C,T,m>::CProperty()
    {
    }

    template<class C, class T,PROPERTY_ACCESS_MODE mCProperty<C,T,m>::CProperty(T v)
    {
        
    assert(WRITEACCESS(this->m_mode));
        
    assert(this->m_write_callback!=NULL);
        
    this->m_write_callback(v);
    }

    template<class C, class T,PROPERTY_ACCESS_MODE mvoid CProperty<C,T,m>::owner(Cc)
    {
        
    assert(c!= NULL);
        
    this->m_class c;
    }

    template<class C, class T,PROPERTY_ACCESS_MODE mCProperty<C,T,m>::CProperty(const CPropertyp)
    {
        if(
    this == &p) return;
        
    this->m_class p.m_class;
        
    this->m_mode p.m_mode;
        
    this->m_read_callback p.m_read_callback;
        
    this->m_write_callback p.m_write_callback;
    }
    template<class C, class T,PROPERTY_ACCESS_MODE mCProperty<C,T,m>::~CProperty()
    {}
    template<class C, class T,PROPERTY_ACCESS_MODE mT CProperty<C,T,m>::operator = (const Tv)
    {
        
    assert(WRITEACCESS(this->m_mode));
        
    assert(this->m_write_callback!= NULL);
        
    this->m_write_callback(v);
        return 
    v;
    }

    template<class C, class T,PROPERTY_ACCESS_MODE mvoid CProperty<C,T,m>::RegisterReadCallback(read_callback c)
    {
        if(!
    READACCESS(this->m_mode)) this->m_read_callback NULL;
        else 
    this->m_read_callback c;
    }
    template<class C, class T,PROPERTY_ACCESS_MODE mvoid CProperty<C,T,m>::RegisterWriteCallback(write_callback c)
    {
        if(!
    WRITEACCESS(this->m_mode)) this->m_write_callback NULL;
        else 
    this->m_write_callback c;
    }
    template<class C, class T,PROPERTY_ACCESS_MODE mCProperty<C,T,m>::operator T()
    {
        
    assert(READACCESS(this->m_mode));
        
    assert(this->m_read_callback != NULL);
        return 
    this->m_read_callback();

    And here is how I'm using it:
    PHP Code:
    CWnd::CWnd(const CWndw)
    {
        if(
    this != &w)
        {
            
    this->parent w.parent;
            
    this->m_hWnd w.hwnd;    // see error 1
        
    }

    PHP Code:
    CControlCControl::operator = (const CControlc)
    {
        if(
    this == &c) return *this;
        
    this->name c.name;
        
    this->m_hWnd c.hwnd;    // see error 1
        
    this->parent c.parent;
        return *
    this;

    PHP Code:
    CObjectCContainer::operator ()(std::string n)
    {
        
    std::vector<CObject*>::iterator m_iterator this->m_elements.begin();
        while(
    m_iterator != this->m_elements.end())
        {
            if(
    m_iterator == this->m_elements.end()) throw("Object not found");
            if(((
    CObject*)(*m_iterator))->name == n) return *(CObject*)(*m_iterator);    // see error 2
            
    ++m_iterator;
        }
        throw(
    "Object not found");

    Now I get the following errors:
    PHP Code:
    (1error C2440'=' cannot convert from 'const GUI::CProperty<C,T,mode>' to 'HWND'    
    (2error C2678binary '==' no operator found which takes a left-hand operand of type 'GUI::CProperty<C,T>' (or there is no acceptable conversion
    Name is declared in CObject as:
    PHP Code:
    CProperty<CObject,std::stringname
    And hwnd is declared in CWControl as:
    PHP Code:
    CProperty<CControl,HWND,PROP_READhwnd
    I know it has something to do with the const keywords, but how do I fix it?

    Grtz

  5. #5
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Code:
    template<class C, class T,PROPERTY_ACCESS_MODE m> CProperty<C,T,m>::operator T() //no const
    
    CControl& CControl::operator = (const CControl& c)
    {
        if(this == &c) return *this;
        this->name = c.name;
        this->m_hWnd = c.hwnd;    // see error 1
        this->parent = c.parent;
        return *this;
    }
    As to the other error, it's a bit hard to follow what is going on. Basically operator T is bad karma. Looking at a piece of code it is hard to tell exactly what this->name means and what type it is. Perhaps the conversions that you are expecting are just not happening and you must force the compiler with an explicit cast to string (and if it is so you should see that any syntactic nicety that operator T seems to promise just fades away).

    You might be overengineering a bit (trying to mimick C# properties?), where it might be so simple just to write simple get and set functions as needed (in a GUI where they probably do something they might need to be virtual, e.g setting text of Window and a Button might do different things). Also in a copy constructor the members of another instance of the same class are already visible, you don't need getters and setters for that. Also a user-defined copy constructor is not necessary if all you do is a simple member-wise copy.
    Last edited by anon; 03-19-2009 at 06:18 AM.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  6. #6
    Registered User
    Join Date
    Mar 2009
    Posts
    10
    Ok so I fixed error 2, being:
    PHP Code:
    (2error C2678binary '==' no operator found which takes a left-hand operand of type 'GUI::CProperty<C,T>' (or there is no acceptable conversion
    This is what I added to my CProperty class:
    PHP Code:
    template<class C, class T,PROPERTY_ACCESS_MODE mbool CProperty<C,T,m>::operator==(const Tv)
    {
        
    assert(this->m_read_callback!=NULL);
        return (
    this->m_read_callback() == v);
    }
    template<class C, class T,PROPERTY_ACCESS_MODE mbool CProperty<C,T,m>::operator!=(const Tv)
    {
        
    assert(this->m_read_callback!=NULL);
        return (!!
    this->m_read_callback() != v);

    But error 1 still remains..

  7. #7
    Registered User
    Join Date
    Mar 2009
    Posts
    10
    Quote Originally Posted by anon View Post
    Code:
    template<class C, class T,PROPERTY_ACCESS_MODE m> CProperty<C,T,m>::operator T() //no const
    
    CControl& CControl::operator = (const CControl& c)
    {
        if(this == &c) return *this;
        this->name = c.name;
        this->m_hWnd = c.hwnd;    // see error 1
        this->parent = c.parent;
        return *this;
    }
    As to the other error, it's a bit hard to follow what is going on. Basically operator T is bad karma. Looking at a piece of code it is hard to tell exactly what this->name means and what type it is. Perhaps the conversions that you are expecting are just not happening and you must force the compiler with an explicit cast to string (and if it is so you should see that any syntactic nicety that operator T seems to promise just fades away).

    You might be overengineering a bit (trying to mimick C# properties?), where it might be so simple just to write simple get and set functions. Also in a copy constructor the members of another instance of the same class are already visible, you don't need getters and setters for that. Also a user-defined copy constructor is not necessary if all you do is a simple member-wise copy.
    I'm not quite following you.
    You are pointing me to my operator T() function, noting it's not a const, but isn't that supposed to be non-const?

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by r0flc0pter
    You are pointing me to my operator T() function, noting it's not a const, but isn't that supposed to be non-const?
    No, conversion functions can be declared const.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    The larch
    Join Date
    May 2006
    Posts
    3,573
    In any case there appears to be const correctness issues. If operator T is used at all in this case, the copy constructor cannot accept the argument by const reference, or all property members need to be declared mutable or something like that.

    But I still don't get what the Property class buys you in the first place. You still have to declare and code the read and write callbacks (there's your getter and setter) but in addition you also have to register the callbacks with the property and wrestle with implicit conversions.

    Actually I don't get why a GUI object (such as a button?) should be copiable in the first place. Aren't you going to be using polymorhism in the first place and hence work with pointers?
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Ban pointers or references on classes?
    By Elysia in forum C++ Programming
    Replies: 89
    Last Post: 10-30-2007, 03:20 AM
  2. sorting with pointer of pointers to array
    By dunpealslyr in forum C++ Programming
    Replies: 6
    Last Post: 10-01-2007, 11:26 PM
  3. Question About Pointer To Pointer
    By BlitzPackage in forum C++ Programming
    Replies: 2
    Last Post: 09-19-2005, 10:19 PM
  4. Could somebody please help me with this C program
    By brett73 in forum C Programming
    Replies: 6
    Last Post: 11-25-2004, 02:19 AM
  5. towers of hanoi problem
    By aik_21 in forum C Programming
    Replies: 1
    Last Post: 10-02-2004, 01:34 PM