The Microsoft VC++ Virtual Property feature






3.80/5 (4 votes)
Jan 7, 2000

164951
Using the __declspec(property) method to enhance legacy code
A lot of legacy C++ code exists wherein member variables are directly exposed using the public or protected keywords instead of simple accessor / mutator functions. For example consider the following simple structure definition
typedef struct tagMyStruct { long m_lValue1; ... // Rest of the structure definition. } SMyStruct;
Scattered throughout the client code that uses this structure will be code like the following:
SMyStruct MyStruct; long lTempValue; MyStruct.m_lValue1 = 100; // Or any other value that is to be assigned to it. ... lTempValue = MyStruct.m_lValue1;
Now if the module that has all the above code is suddenly required to be used in a thread safe environment, you run into a problem. Because no accessor or mutator functions exist, you cannot just put a critical section (or mutex) within the definition of SMyStruct and protect m_lValue1 or any of the other public member variables.
If it is guaranteed that you will be using the Microsoft Visual C++ compiler then there is an easy solution at hand.
Just enhance the structure as follows:
typedef struct tagMyStruct { __declspec(property(get=GetValue1, put=PutValue1)) long m_lValue1; ... // Rest of the structure definition. long GetValue1() { // Lock critical section return m_lInternalValue1; // Unlock critical section. } void PutValue1(long lValue) { // Lock critical section m_lInternalValue = lValue; // Unlock critical section } private: long m_lInternalValue1; // Define critical section member variable. } SMyStruct;That's all.
For code such as
MyStruct.m_lValue1 = 100
the compiler will automatically substitute MyStruct.PutValue1(100)
For code like
lTempValue = MyStruct.m_lValue1the compiler will substitute
lTempValue = MyStruct.GetValue1()
The possibilities this opens up are many. You can even use this to add reference counting to legacy structures and classes.