Properties in C++

Properties in C++

When I wrote a property using C#, I wondered why such a feature doesn't exist in C++. It was a challenging question and because I know how important such a thing is to C++ developers, I spent three days developing this article. I hope you will find it useful also.

What Properties Are

Properties are like variables that store data, but trigger events that fire when reading or writing data from them. In other words, a property is an interactive variable evaluating itself and having different values when reading and writing to it.

It's easy to write a class using a language like C# that contains properties, but it seems impossible to do with C++ because the C++ complier doesn't support properties the way that C# does. For this reason, I have written this article to show you how to write C++ classes having properties like those found in C#.

You will understand how to use the macros that were written to declare and implement properties. If you are an expert C++ developer and you need to understand how it works, you will not face any problem in reading the macros defined in "Properties.h".

Why Properties Are Important

Imagine that you need to write an object that represents a person. This object may contain data such as:

Full Name     Age     Year of birth     Gender

It could be written using C++, as follows:

class Person {
public:
   Person( ){}
   virtual ~Person( ){}

private:    //data members

   char m_fName[20];
   char m_lName[20];

   UINT m_YearOfBirth;
   bool m_bGender;
};
Note: In most cases, you can't define a data member as public to be used directly because the data member should be maintained through the business logic that is implemented by the object.

If you need to get or set the value of m_bGender, you need to implement methods as shown below.

class Person {
public:
   Person( ){}
   virtual ~Person( ){}

   void SetGender(bool bGender) {m_bGender = bGender;}
   bool GetGender() {return m_bGender;}

private:    //data members

   char m_fName[20];
   char m_lName[20];

   UINT m_YearOfBirth;
   bool m_bGender;
};

The disadvantage of using this method is that you need to know which method should be used to change the Gender. But with properties, life is better because to do the same thing all you need is to know the name of the property you need. Also, a single property can support different data types. In other words, in the example, you can let Gender accept string and Boolean values to use it, as shown below.

Person.Gender = "Male";

or

Person.Gender = true;

Of course, life now became much easier with Properties and the code now also became more readable.

Property Declaration

Now, I will show you how to write properties. Start by writing the Gender property as shown below.

class Person {
public:
   Person( ){}
   virtual ~Person( ){}

   Begin_Property(char*,Gender)
      __get(char*,Gender)
      _set(char*);

      _get(bool);
      _set(bool);

      __release(Gender)
   End_Property(Gender)

private:    //data members

   char m_fName[20];
   char m_lName[20];

   UINT m_YearOfBirth;
   bool m_bGender;
};

Now, look at the code. I started with the Property definition by using the Begin_Property macro. It takes two parameters, property data type and property name. Because Gender property is a string property, it should be char*. After I started defining my property, I needed to declare the events get(ers) and set(ers) that will fire each time it's being used, as shown below.

// This will fire _set(bool) event
Person.Gender = true;
// this will fire _get(bool) event
bool gender = Person.Gender ;
//This will fire _set(char*)
Person.Gender = "Male";
//This will fire _get(char*)
printf("Gender :%s\n",(char*)Person.Gender);

_get and _set are two macros that take one parameter that represent the data types that can be accepted by the property. You can notice the data type of _set and _get events independent of the data type of property. In other words, although the data type of the "Gender" property is char*, it has bool getters and setters. In this way, it can accept as Boolean or string values as shown above.

The last two macros I used are _release to release the memory it allocates (this will be covered in detail later) and End_Property to close property declaration and both macros take property name as a parameter.

Property Implementation

After declaring properties, you need to implement set(ers) and get(ers). You can do so in the same place as shown below.

.
.
.

Begin_Property(char*,Gender)
   __get(char*,Gender)
   _set(char*)
   {
      //do something here
      return Gender;
   }

   _get(bool)
   {
      //do something here
      return iValue;
   }
   _set(bool)
   {
      //do something here
      return iValue;
   }

   __release(Gender)
End_Property(Gender)
.
.
.

You can implement it by using implementation macros, but before showing you how to use those macros, let me explain two other points: what macro __get is and why set(ers) should return a value. All you need to do in _get(char*) is just to return a pointer to it this way: "return Gender;". This is what __get does. __get is the default getter of the Property; because "Gender" is a char* property, you used it in this way: "__get(char*,Gender)".

Now, to the second question, why should set(ers) return value like get(ers)? Simply, in C++ set(ers) can act as get(ers), as shown below.

bool bGender = Person.Gender = true;

Now, implement the Gender Property by using Imp_set and Imp_get macros. Both macros take three parameters: data type, Class name, and property name, as shown below.

Imp_set(char*,Person,Gender)
{
   PROPERTY_PROLOGUE(Person,Gender)

   if (!Gender) Gender = new char[7];

   if (strlen(iValue)<6 )
   {
      int result;
      if ((result=strcmp(iValue,"Male"))==0)
         pThis->m_bGender = true;
      else
      {
         if ((result=strcmp(iValue,"Female"))==0)
         pThis->m_bGender = false;
      }

      if(result==0) strcpy(Gender,iValue);
   }
   return Gender;
}

Imp_set(bool,Person,Gender)
{
   PROPERTY_PROLOGUE(Person,Gender)

   if (!Gender) Gender = new char[7];

   if (pThis->m_bGender = iValue)
      strcpy(Gender,"Male");
   else
      strcpy(Gender,"Female");

   return (bool)iValue;
}

Imp_get(bool,Person,Gender)
{
   PROPERTY_PROLOGUE(Person,Gender)
   return pThis->m_bGender;
}

Because set(ers) and get(ers) can't access class members directly, you used the PROPERTY_PROLOGUE macro. It defines a pointer to the class of the property as shown above, called "pThis".

Also, in class termination, you need to free the memory and any allocated resources being used by the property. This is done by using the function __release macro. __release is a default release macro and its job is done as shown below.

if (Gender)
{
   delete Gender;
   Gender = NULL;
}

You also can implement release events yourself by using _release and Imp_release, as shown below.

Imp_release(Person,Gender)
{
   // Release allocated resources here.
}

The Demo Project

This project demonstrates how to write properties and how properties can affect each other. For example, in the person class, the YearOfBirth property changes the age value property and vice versa. Also, you can use class as property datatype; for example, I used CTime as a datatype of "LeaveDate" and "ContractDate" properties.

Finally, I hope I had covered the subject as much as I can/ For any inquires feel free to email me. Thanks a lot.



About the Author

Mohamed Shuaib

Dears I'm from Cairo, Egypt. I'm using Visual C++ since 1994 Also I worked on areas like VB, VB.Net, ASP.NET, C# ,Pocket pc applications. If you like any of my articles or there are any suggested changes that can the way I code, or write articles Please feel free to email me at sha3sha3_79@hotmail.com.

Downloads

Comments

  • comment

    Posted by qwer_boo on 12/04/2010 02:31am

    ccccccccc

    Reply
  • comments

    Posted by Me_SAC on 06/24/2010 01:04am

    This is really good article..

    Reply
  • Ardehendu

    Posted by Ardhendu Paul on 02/15/2010 12:29am

    Good

    Reply
  • Visual C++ Has property, here is the sample. I have this in my application!

    Posted by silicon on 01/09/2007 10:35pm

    Visual C++ Has property, here is the sample. I have this in my application! private: String __gc * _username; __property String* get_Username() { return this->_username; } __property void set_Username(String* value) { this->_username = value; } It does everything C# handles!

    • Yes, of course

      Posted by DaMagic on 01/10/2007 01:18pm

      Yes, of course, if you program in managed C++ under .NET (managed extensions).

      Reply
    • Formatted output

      Posted by silicon on 01/09/2007 10:36pm

      private: String __gc * _username; 
      
         __property String* get_Username()
              {
                  return this->_username;
              }
          __property void set_Username(String* value)
              {
                  this->_username = value;
              }

      Reply
    Reply
  • Why properties in C++ ?

    Posted by alnikolov on 01/09/2007 04:10am

    I am a bit surprised, even annoyed seeing article like this. If you are going to write code in C++ you should think in C++. There is no need for properties in C++ at all. I have been writing C++ code for the last 15 years and I have not encountered even a single instance where I really need properties. On a different note the __declrspec(property()) syntax is not standard b it is Microsoft specific extension.

    Reply
  • re: the C++ complier doesn't support properties?

    Posted by cjones286 on 01/02/2007 08:40am

    Some do, some dont. gcc does not support __declspec(property). I found this article very useful.

    Reply
  • the C++ complier doesn't support properties ?

    Posted by BauerSd on 01/02/2007 06:27am

    >>the C++ complier doesn't support properties
    This isn't correct, see as Ex.
    ...
    	void setYearOfBirth(UINT uiYearOfBirth)
    	{
    		m_YearOfBirth = uiYearOfBirth;
    	}
    	UINT getYearOfBirth()
    	{
    		return m_YearOfBirth;
    	}
    ...
    
    __declspec(property(get=getYearOfBirth, put=setYearOfBirth)) UINT YearOfBirth;
    
    --
    Siggi

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Java developers know that testing code changes can be a huge pain, and waiting for an application to redeploy after a code fix can take an eternity. Wouldn't it be great if you could see your code changes immediately, fine-tune, debug, explore and deploy code without waiting for ages? In this white paper, find out how that's possible with a Java plugin that drastically changes the way you develop, test and run Java applications. Discover the advantages of this plugin, and the changes you can expect to see …

  • On-demand Event Event Date: September 10, 2014 Modern mobile applications connect systems-of-engagement (mobile apps) with systems-of-record (traditional IT) to deliver new and innovative business value. But the lifecycle for development of mobile apps is also new and different. Emerging trends in mobile development call for faster delivery of incremental features, coupled with feedback from the users of the app "in the wild." This loop of continuous delivery and continuous feedback is how the best mobile …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds