Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: __property keyword and virtual functions



Permlink Replies: 2 - Last Post: Oct 3, 2014 10:20 AM Last Post By: Jean-Milost Rey... Threads: [ Previous | Next ]
Jean-Milost Rey...

Posts: 23
Registered: 11/8/11
__property keyword and virtual functions
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 2, 2014 9:20 AM
Hello,

I have a bug that leaves me a little puzzled. I'm writing a component inherited from a TPanel. In this component, I have overridden a lot of properties, among them the Align property, as in the following example
#define M_Panel_Show_Caption false
#define M_Panel_Default_Align alNone
...
    __property TAlign Align = {read = GetAlign, write = SetAlign, default = M_Panel_Default_Align};
    ...
    __property bool ShowCaption = {read = GetShowCaption, write = SetShowCaption, default = M_Panel_Show_Caption};
 
protected:
    /**
    * Get alignment mode
    *@returns alignment mode
    */
    virtual TAlign __fastcall GetAlign();
 
    /**
    * Set alignment mode
    *@param align - alignment mode
    */
    virtual void __fastcall SetAlign(TAlign align);
 
    ...
 
    /**
    * Get show caption flag
    *@returns show caption flag
    */
    virtual bool __fastcall GetShowCaption();
 
    /**
    * Set show caption flag
    *@param value - if true, caption is shown
    */
    virtual void __fastcall SetShowCaption(bool value);


In my calling project, I try to call my align property as follow:
        std::auto_ptr<MyPanel> pBackgroundPanel(new MyPanel(m_pForm.get()));
        pBackgroundPanel->Name = "paDialogBackground";
        pBackgroundPanel->Align = alTop;


After this call, I was surprised that my Align property remained to alNone. I have debugged my code, and I found that the setter that my Align property calls is ... SetShowCaption!!!

When I modify my code as follow, everything works fine
#define M_Panel_Show_Caption false
#define M_Panel_Default_Align alNone
...
    __property TAlign Align = {read = GetAlign, write = SetAlign, default = M_Panel_Default_Align};
    ...
    __property bool ShowCaption = {read = GetShowCaption, write = SetShowCaption, default = M_Panel_Show_Caption};
 
protected:
    /**
    * Get show caption flag
    *@returns show caption flag
    */
    virtual bool __fastcall GetShowCaption();
 
    /**
    * Set show caption flag
    *@param value - if true, caption is shown
    */
    virtual void __fastcall SetShowCaption(bool value);
 
...
 
private:
    /**
    * Get alignment mode
    *@returns alignment mode
    */
    TAlign __fastcall GetAlign();
 
    /**
    * Set alignment mode
    *@param align - alignment mode
    */
    void __fastcall SetAlign(TAlign align);


I don't understand what's wrong. I assumed that the __property keyword didn't support virtual functions, but I found this document that clearly shows otherwise: http://docwiki.embarcadero.com/RADStudio/XE6/en/Class_Methods, where GetStrProp and SetStrProp are virtual getter and setter in the sample code

NOTE I'm using c++ builder XE4

Regards

Edited by: Jean-Milost Reymond on Oct 2, 2014 9:21 AM

Edited by: Jean-Milost Reymond on Oct 2, 2014 9:23 AM
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: __property keyword and virtual functions [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 2, 2014 9:48 AM   in response to: Jean-Milost Rey... in response to: Jean-Milost Rey...
Jean-Milost wrote:

I have a bug that leaves me a little puzzled. I'm writing a component
inherited from a TPanel. In this component, I have overridden a lot of
properties, among them the Align property, as in the following example

You should not be redeclaring your own getter/setter methods for existing
properties. You should use the existing properties and simply declare new
'default' values for them (and make sure your constructor actually assigns
those values), eg:

#define M_Panel_Show_Caption false
#define M_Panel_Default_Align alNone
 
class MyPanel : public TPanel
{
public:
    __fastcall MyPanel(TComponent *Owner);
 
__published:
    __property Align = {default = M_Panel_Default_Align};
    __property ShowCaption = {default = M_Panel_Show_Caption};
};
 
__fastcall MyPanel::MyPanel(TComponent *Owner)
    : TPanel(Owner)
{
    Align = M_Panel_Default_Align;
    ShowCaption = M_Panel_Show_Caption;
}


If you need to react to changes to the Align property, override the virtual
SetBounds() method (TControl::SetAlign() is not virtual).

If you need to react to changes to the ShowCaption property, well unfortunately
there is no notification for that. When ShowCaption is changed, all it does
is calls Invalidate() to redraw the panel. What you could do, though, is
declare a private variable to hold the original value, and then override
the virtual Paint() method to check if the current ShowCaption value is different
than the variable's value, and if so then update the variable and post a
notification back to yourself.

I don't understand what's wrong.

You are probably causing conflicts between your custom SetAlign() and SetShowCaption()
methods and the existing methods of the same names that already exist in
TControl and TPanel. Try giving your custom methods more unique names.

I assumed that the __property keyword didn't support virtual functions

Yes, it does.

--
Remy Lebeau (TeamB)
Jean-Milost Rey...

Posts: 23
Registered: 11/8/11
Re: __property keyword and virtual functions [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 3, 2014 10:20 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Hi Remy,

I finally found what was the problem in my class. I declared some functions encapsulated inside a #define _DEBUG condition. These functions worked well as long as my component package and the project that use them were both compiled in debug or in release. But if one was compiled in debug and other in release, the vTable of the class that contain the _DEBUG functions is shifted, as the target project seems to use the release component header with the debug compiled package, or vice versa.

Thank you again for your help,
Regards
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02