Libpropc++�Properties in C++

Properties are pseudo-variables getting/setting which causes side-effects. For example, assignment to a color property of Widget class would cause the change of the color of a widget onscreen:

widget.color = "red";

Libpropc++ is the C++ library that implements properties in Standard C++.

The most interesting feature of libpropc++ is that it supports binding properties—that is, auto-synchronizing values of properties—so that when the value of one property changes, values of the other automatically changes accordingly.

Every time you write a GUI application, you in fact natively use binding properties: You need to synchronize e.g. the checked state of a checkbox and sensitivity or visibility of another conrol. You need to synchronize application preferences with the state of the UI and so forth.

With libpropc++, you can do the same more quickly, with fewer errors, more easily, and more maintainably. The most time spent while developing a GUI application is writing callbacks used to synchronize the values of several objects' properties. The most common cause of errors in GUI applications is incorrect synchronization of properties that should be synchronized. Save your time by using a ready, already debugged solution instead of repeated coding that's the same for every function.

Defining Properties in libpropc++

This example illustrates how to define properties in libpropc++:

#include <propc++/property.h>

class Widget
{
   // ...
   Widget() : color(*this) { }
   // ...
   Color get_color() const;
   void set_color(Color color);
   // ...
   prop::Property<Widget, Color, &Widget::set_color,
                  &Widget::get_color> color;
   // ...
};

After this, the property can be used just like a normal variable: assignment to it calls set_color() and reading its value calls get_color().

However, the above approach has the deficiency that a property unnecessarily holds a pointer to the object (to a widget, in our case), and so takes 4 bytes (for every object) on a 32-bit system.

As such, libpropc++ provides an alternative way to define properties that does not use any extra memory, so called simple properties:

#include <propc++/property_simple.h>

class Widget
{
   // ...
   Widget() : color(*this) { }
   // ...
   Color get_color() const;
   void set_color(Color color);
   // ...
   prop::simple::Property<Widget, Color> color() {
     return prop::property(*this, set_color, get_color);
   }
   // ...
};

Then, widget.color() = "red"; would mean the same as widget.set_color("red");.

Properties are classified to as read-write, read-only, and write-only properties. Read-write properties were demonstrated above; for read-only properties, use ReadProperty (with only a get_*() function) instead of Property and for write-only properties, use WriteProperty (with only a set_*() function).

Note that get_*() functions are called getter or read accessor and set_*() functions are called setter, write accessor, or modifier.

Binding Properties

Binding properties together is the most powerful feature of libpropc++. (Also see this article about binding properties in general and implementation strategies.)

Binding properties means that the user directs the library to automatically keep values of several properties synchronized with each other; that is, when one of the bound properties changes, the other automatically changes accordingly.

A typical example would be:

#include <propc++/bindable.h>

// ...
checkbox.checked.bind(frame.visible);
// ...

The above could be used to make a frame visible only when a checkbox is checked. The above statement is a warranty that the frame will be visible when and only when the checkbox is checked. Only one line of code, instead of about 6–7 or more lines for this as in most GUI toolkits! All automatically and no place for an error!

A common source of errors in GUI applications is that when a programmer tries to bind together two properties, A and B; he forgots the initial assignment B = A;. The above one-line example saves you from this error.

Well, if you want to make this error, you can:

checkbox.checked.bind_unsafe(frame.visible);

This binds the properties together but does not accomplish the initial assignment of frame.visible = checkbox.checked; before binding. Use bind_unsafe() at your own risk.

Sometimes, you need to bind two checkboxes (or more often a checkbox and a check menu item) to be checked/unchecked simulateously (when one is checked, the other should be checked also and vice versa). For this, use two-way or mutual binding:

prop::mutual::bind(checkbox1.checked, checkbox2.checked);

Want one to be checked when one is unchecked and vice versa? Use binding with the transforming functor:

prop::mutual::bind(checkbox1.checked, checkbox2.checked,
                   std::negate(), std::negate());

std::negate (defined in <functional> header) is an STL functor that negates a boolean value.

This can be simplified to:

prop::mutual::bind_negated(checkbox1.checked, checkbox2.checked);

For a more sophisticated example:

prop::mutual::bind(meters_entry.number, kilometers_entry.number,
                   std::bind2nd(std::multiply(), 1000),
                   std::bind2nd(std::divide  (), 1000));

This would bind values of meters and kilometers spin entries with transformation of the value by functors (multiply/divide by 1000). You provide two functors that are the inverse of each other.

By using transforming functors, you also can bind properties of different types. If the types are convertible to each other, you can omit transforming functors and the values will be converted to each other by using C++ type conversions.

Signalling

Signal programming (otherwise known as an observer pattern) is sending synchronous signals on some events (such as property value changes). So-called listeners register to hear a signal. One signal can be listened to by several listeners.

You can read more about signal programming in the documentation of the libsigc++ library.

Libpropc++ can be used either with or without libsigc++. (It depends simply on the include path settings of your compiler.)

Libpropc++ provides a partial re-implementation of libsigc++. Use this re-implementation if you want to use libpropc++ to write commercial software because the license of libsigc++ requires any software using libsigc++ to be open source.

Notes on Compilation and Bug Reporting

Libpropc++ is written in Standard C++ and should work with any comforming compiler.

Current status of compilers support:

GCC/G++
<3.0 unsupported, >=3.0 supported.

Please test libpropc++ with other compilers and report whether it compiles and any error/warning messages.

Report any bugs to Victor Porton, porton@ex-code.com.

Installation

Libpropc++ currently consists only of header files and needs no special installation. Just unpack it to the appropriate directory and point your compiler include path to it.

Licensing and Ordering

Libpropc++ has dual licensing:

LGPL 2.1
You are allowed to use libpropc++ only for open source software (because of LGPL issues related with templates).
Commercial License
Can be used to develop commercial applications.

Order/download libpropc++ at http://ex-code.com/propcpp/.

If you want to integrate libpropc++ into your own C++ library, contact Extreme Code.

References

  1. Binding Together Properties of Objects. Victor Porton. 2004.
  2. Online documentation of libpropc++.
  3. Online documentation of libsigc++.


About the Author

Victor Porton

C++, Ada95, Python, many other languages.

Comments

  • Similar system for defining properties... though I like yours better

    Posted by Jason King on 09/27/2004 01:46pm

    This looks to be a very nice, complete library. I especially like the use of templates. I hope that instead of licensing you would think about adding it to boost or some other free library. If people are interested in a similar system or want to know an alternate way on how defining the properties can be done, check out an article I wrote at http://www.codeproject.com/cpp/genericproperty.asp

    Reply
  • This is an advertisement!!!

    Posted by KevinHall on 09/24/2004 06:24pm

    Please don't post ads. Also the implementation of simple properties in this library is too complex and doesn't cover all cases well. Although I admit, the idea of binding properties is interesting.

    • About value passing

      Posted by porton on 09/26/2004 03:00pm

      In the docs (http://ex-code.com/propcpp/) it is explained that for types with slow copying you should use "const T&" instead of "T" as the T template argument. This solves the problem of passing by value. With "const" classes only ReadProperty (not Property and WriteProperty) work. Also note that this library is free for use in free software.

      Reply
    • RE: Simple properties

      Posted by KevinHall on 09/25/2004 11:59pm

      You pass properties by value.  This is not a big deal if you deal with fundamental types, but if you have a class that performs deep copies, the overhead can become overwhelming.  In these instances it's better to pass by reference.
      
      I also didn't see (granted I didn't spend a huge amount of time analyzing your code) a way to handle properties from "const" classes.  If a class was "const", or you had a const reference, could you still read the property while creating a compile-time error for setting the property?
      
      As far as being complex, I was able to implement my own simple property template with about 20 lines of property code and 20 lines of utility template code that protects against the const cases.
      
      And as far a press-releases, I'd try to e-mail the site admin to see if there is a place to post press-releases.  People rarely like reading an article to find out at the end it is really an ad / press-release.

      Reply
    • Well, sorry, but...

      Posted by porton on 09/24/2004 06:38pm

      Well, not advertisement but a press-release containing a short introductory tutorial. Anyway sorry, I though this kind of materials is interesting and useful for site readers. I probably mis-understood the site's rules, they may be too vague. What you mean by "the implementation of simple properties... doesn't cover all cases well"? Which cases you mean?

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

Top White Papers and Webcasts

  • Live Event Date: September 16, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Are you starting an on-premise-to-cloud data migration project? Have you thought about how much space you might need for your online platform or how to handle data that might be related to users who no longer exist? If these questions or any other concerns have been plaguing you about your migration project, check out this eSeminar. Join our speakers Betsy Bilhorn, VP, Product Management at Scribe, Mike Virnig, PowerSucess Manager and Michele …

  • As mobile devices have pushed their way into the enterprise, they have brought cloud apps along with them. This app explosion means account passwords are multiplying, which exposes corporate data and leads to help desk calls from frustrated users. This paper will discover how IT can improve user productivity, gain visibility and control over SaaS and mobile apps, and stop password sprawl. Download this white paper to learn: How you can leverage your existing AD to manage app access. Key capabilities to …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds