Click here to Skip to main content
11,478,066 members (72,911 online)
Click here to Skip to main content

Implementing Properties In C++

, 2 Apr 2003 162.5K 801 49
Rate this:
Please Sign up or sign in to vote.
Implementing properties on c++ objects

Introduction

This project tries to simulate the property behaviors that exist in C# (and other languages...) in C++ without using any extensions. Most libraries or compilers that implement properties in C++ use extensions such as Managed C++ or C++ Builder or they use set and get methods which look like normal methods rather than properties.

Let us first see what a property is. A property acts like a field or member variable from the point of view of the library user, but it accesses the underlying variable through read or write methods or set or get methods.

For example, I have class A and property Count, I can write the following code.

A foo;
    
cout <<  foo.Count;

The Count property actualy calls the get function to return the value of the required variable. One of the main advantage of using properties instead of directly accessing the variable is that you can set the property as read only (where you are only allowed to read the variable, not change it), write only or both read write, so let us implement it.

We need to be able to do the following.

//-- Will call the get function to get the underlying value
int i = foo.Count;

//-- Will call the set function to set the value
foo.Count = i;

So it is obvious that we need to overload the = operator for setting the variable and also the return type (which we will show a little later).

We will implement a class called property which will act exactly like a property, as the following example shows.

template<typename Container, typename ValueType, int nPropType>
    class property {}

This Template class will represent our property. The Container is the type of the class that will contain the variable, the set & get methods and the property. ValueType is the type of the internal variable itself. nPropType is the access type of the property (read only, write only or read write).

So now we need to set a pointer to the set and get method from the container class to the property and also override the operator = so that the property will act like the variable, so let's see the full listing of the property class.

#define READ_ONLY 1
#define WRITE_ONLY 2
#define READ_WRITE 3

template <typename Container, typename ValueType, int nPropType>
    class property
{
public:
    property()
    {
        m_cObject = NULL;
        Set = NULL;
        Get = NULL;
    }

    //-- Set a pointer to the class that contain the property --
    void setContainer(Container* cObject)
    {
        m_cObject = cObject;
    }

    //-- Set the set member function that will change the value --
    void setter(void (Container::*pSet)(ValueType value))
    {
        if((nPropType == WRITE_ONLY) || (nPropType == READ_WRITE))
            Set = pSet;
        else
            Set = NULL;
    }

    //-- Set the get member function that will retrieve the value --
    void getter(ValueType (Container::*pGet)())
    {
        if((nPropType == READ_ONLY) || (nPropType == READ_WRITE))
            Get = pGet;
        else
            Get = NULL;
    }

    //-- Overload the = operator to set the value using the set member --
    ValueType operator =(const ValueType& value)
    {
        assert(m_cObject != NULL);
        assert(Set != NULL);
        (m_cObject->*Set)(value);
        return value;
    }

    //-- Cast the property class to the internal type --
    operator ValueType()
    {
        assert(m_cObject != NULL);
        assert(Get != NULL);
        return (m_cObject->*Get)();
    }

private:
    //-- Pointer to the module that contains the property --
    Container* m_cObject;
    //-- Pointer to set member function --
    void (Container::*Set)(ValueType value);
    //-- Pointer to get member function --
    ValueType (Container::*Get)();};

So now let's examine each piece.

The following code just sets the Container pointer to a valid instance that contains the property we're going to access.

void setContainer(Container* cObject)
{
    m_cObject = cObject;
}

The following code sets a pointer to the get and set member functions of the container class. The only restrictions are that the set member function must take a single parameter and return void and the get member function must take no parameters but return the value type.

//-- Set the set member function that will change the value --
void setter(void (Container::*pSet)(ValueType value))
{
    if((nPropType == WRITE_ONLY) || (nPropType == READ_WRITE))
        Set = pSet;
    else
        Set = NULL;
}

//-- Set the get member function that will retrieve the value --
void getter(ValueType (Container::*pGet)())
{
    if((nPropType == READ_ONLY) || (nPropType == READ_WRITE))
        Get = pGet;
    else
        Get = NULL;
}

The first operator in the following code is the = operator, which calls the set member of the container passing the value. The second operator makes the entire property class act as the ValueType so it returns the value returned by the get function.

//-- Overload the = operator to set the value using the set member --

ValueType operator =(const ValueType& value)
{
    assert(m_cObject != NULL);
    assert(Set != NULL);
    (m_cObject->*Set)(value);
    return value;
}

//-- To make possible to cast the property class to the internal type --
operator ValueType()
{
    assert(m_cObject != NULL);
    assert(Get != NULL);
    return (m_cObject->*Get)();
}

Now let's see how to use it.

As shown below, the PropTest class implements a simple property called Count. The actual value will be stored and retrieved from the private member variable m_nCount, through the get and set methods. The get and set methods can have any name as long as their addresses are passed to the property class as shown in the constructor of the PropTest object. The line property<PropTest,int,READ_WRITE> Count; says that we have a read & write property of type integer in class PropTest called Count. Now you can call Count as normal member variable even though you're really calling the set and get methods indirectly.

The initialization shown in the constructor of the PropTest class is necessary for the property class to work.

class PropTest
{
public:
    PropTest()
    {
        Count.setContainer(this);
        Count.setter(&PropTest::setCount);
        Count.getter(&PropTest::getCount);
    }
    
    int getCount()
    {
        return m_nCount;
    }

    void setCount(int nCount)
    {
        m_nCount = nCount;
    }

    property<PropTest,int,READ_WRITE> Count;

private:
    int m_nCount;
};

As shown below you use the Count property as though it were a normal variable.

int i = 5,
    j;

PropTest test;

test.Count = i;    // call the set method --

j = test.Count;    //-- call the get method --

For read only properties you create an instance of the property as follows

property<PropTest,int,READ_ONLY > Count;

And for write only properties you would create an instance of the property as follows

property<PropTest,int,WRITE_ONLY > Count;

Note: If you set the property to read only and you try to assign to it, it will cause an assertion in debug builds. Similarly, if you set the property to write only and you try to read it an assertion will occur in debug builds.

Conclusion:

This shows how to implement properties in C++ using standard C++ without any extensions. Naturally, using set and get methods are more efficient because with this method you have a new instance of the property class per each property.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Emad Barsoum
Architect
United States United States
No Biography provided

Comments and Discussions

 
Generaloverloading &lt;&lt; and >> operator Pin
niko28829-Apr-07 11:01
memberniko28829-Apr-07 11:01 
GeneralYET A simple way to implement properties.... Pin
AnandChavali21-Dec-06 1:13
memberAnandChavali21-Dec-06 1:13 
GeneralRe: YET A simple way to implement properties.... Pin
AnandChavali21-Dec-06 1:19
memberAnandChavali21-Dec-06 1:19 
GeneralA simpler property Pin
BauerSd4-Oct-04 1:20
memberBauerSd4-Oct-04 1:20 
GeneralRe: A simpler property Pin
Emad Barsoum4-Oct-04 7:57
memberEmad Barsoum4-Oct-04 7:57 
GeneralYour implementation needs some improvements Pin
Ghost-Rider26-Feb-04 23:30
memberGhost-Rider26-Feb-04 23:30 
GeneralRe: Your implementation needs some improvements Pin
masud_masud22-Mar-04 11:39
membermasud_masud22-Mar-04 11:39 
GeneralExtra assignment operator Pin
HChristiaans13-Jul-03 13:55
sussHChristiaans13-Jul-03 13:55 
GeneralRe: Extra assignment operator: like this Pin
cimnik02910-Apr-04 13:09
membercimnik02910-Apr-04 13:09 
GeneralRe: Extra assignment operator Pin
RAD CPP2-Sep-06 23:23
memberRAD CPP2-Sep-06 23:23 
AnswerRe: Extra assignment operator Pin
Joseph Maurer24-May-12 7:48
memberJoseph Maurer24-May-12 7:48 
GeneralA little simplification... Pin
Ken Keray12-Apr-03 14:02
memberKen Keray12-Apr-03 14:02 
GeneralRe: A little simplification... Pin
Emad Barsoum12-Apr-03 14:23
memberEmad Barsoum12-Apr-03 14:23 
GeneralRe: A little ssugestions... Pin
peterchen20-May-03 11:33
memberpeterchen20-May-03 11:33 
GeneralRe: A little ssugestions... Pin
6Qing8827-Apr-09 0:49
member6Qing8827-Apr-09 0:49 
GeneralOther implementation Pin
Dalle9-Apr-03 12:53
memberDalle9-Apr-03 12:53 
GeneralSorry for the long post above Pin
Dalle9-Apr-03 12:54
memberDalle9-Apr-03 12:54 
General[Message Deleted] Pin
P. Schregle8-May-03 22:47
memberP. Schregle8-May-03 22:47 
GeneralRe: Other implementation Pin
Dalle9-May-03 0:11
memberDalle9-May-03 0:11 
QuestionCould property own the value? Pin
davidmontgomery8-Apr-03 22:20
memberdavidmontgomery8-Apr-03 22:20 
AnswerRe: Could property own the value? Pin
Dalle9-Apr-03 5:03
memberDalle9-Apr-03 5:03 
GeneralRe: Could property own the value? Pin
davidmontgomery9-Apr-03 21:08
memberdavidmontgomery9-Apr-03 21:08 
GeneralRe: Could property own the value? Pin
Dalle9-Apr-03 23:45
memberDalle9-Apr-03 23:45 
AnswerRe: Could property own the value? Pin
cimnik0299-Apr-04 16:54
membercimnik0299-Apr-04 16:54 
GeneralOperator support Pin
Dalle4-Apr-03 12:15
memberDalle4-Apr-03 12:15 
GeneralRe: Operator support Pin
Emad Barsoum8-Apr-03 7:44
memberEmad Barsoum8-Apr-03 7:44 
Questionwhy 2 part initialization? Pin
RabidCow3-Apr-03 21:35
memberRabidCow3-Apr-03 21:35 
AnswerRe: why 2 part initialization? Pin
Emad Barsoum4-Apr-03 8:05
memberEmad Barsoum4-Apr-03 8:05 
QuestionWhat's the point of properties anyways? Pin
Swinefeaster3-Apr-03 9:04
memberSwinefeaster3-Apr-03 9:04 
AnswerRe: What's the point of properties anyways? Pin
Anonymous4-Apr-03 6:44
sussAnonymous4-Apr-03 6:44 
GeneralRe: What's the point of properties anyways? Pin
Swinefeaster4-Apr-03 8:19
memberSwinefeaster4-Apr-03 8:19 
GeneralRe: What's the point of properties anyways? Pin
RabidCow4-Apr-03 11:34
memberRabidCow4-Apr-03 11:34 
GeneralRe: What's the point of properties anyways? Pin
Anonymous7-Apr-03 7:33
sussAnonymous7-Apr-03 7:33 
GeneralRe: What's the point of properties anyways? Pin
Andrew K15-May-04 16:50
memberAndrew K15-May-04 16:50 
AnswerRe: What's the point of properties anyways? Pin
Emad Barsoum4-Apr-03 8:20
memberEmad Barsoum4-Apr-03 8:20 
GeneralRe: What's the point of properties anyways? Pin
FlyingRat8-Apr-03 0:59
memberFlyingRat8-Apr-03 0:59 
AnswerRe: What's the point of properties anyways? Pin
peterchen22-May-05 6:17
memberpeterchen22-May-05 6:17 
GeneralGreat Idea, but one flaw as I see it .... Pin
David Patrick3-Apr-03 3:07
memberDavid Patrick3-Apr-03 3:07 
GeneralRe: Great Idea, but one flaw as I see it .... Pin
Emad Barsoum3-Apr-03 7:33
memberEmad Barsoum3-Apr-03 7:33 
GeneralRe: Great Idea, but one flaw as I see it .... Pin
sage2558-Apr-03 5:27
membersage2558-Apr-03 5:27 
GeneralRe: Great Idea, but one flaw as I see it .... Pin
Emad Barsoum8-Apr-03 7:46
memberEmad Barsoum8-Apr-03 7:46 
GeneralRe: Great Idea, but one flaw as I see it .... Pin
Shmulik Flint9-Apr-03 2:40
memberShmulik Flint9-Apr-03 2:40 
GeneralGreat !! Pin
Daniel GARRIVIER3-Apr-03 0:54
memberDaniel GARRIVIER3-Apr-03 0:54 
GeneralRe: Great !! Pin
Emad Barsoum3-Apr-03 7:39
memberEmad Barsoum3-Apr-03 7:39 
GeneralRe: Great !! Pin
RabidCow4-Apr-03 11:42
memberRabidCow4-Apr-03 11:42 
GeneralNice one Pin
Mohammed Hossny2-Apr-03 22:48
memberMohammed Hossny2-Apr-03 22:48 
GeneralAnd another simple way... Pin
Keias2-Apr-03 21:16
memberKeias2-Apr-03 21:16 
GeneralRe: And another simple way... Pin
Emad Barsoum2-Apr-03 22:02
memberEmad Barsoum2-Apr-03 22:02 
GeneralRe: And another simple way... Pin
peterchen2-Apr-03 22:20
memberpeterchen2-Apr-03 22:20 
GeneralRe: And another simple way... Pin
Emad Barsoum3-Apr-03 7:45
memberEmad Barsoum3-Apr-03 7:45 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150520.1 | Last Updated 3 Apr 2003
Article Copyright 2003 by Emad Barsoum
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid