Implementing the Property in C
Summary:
This article describes how to implement "property" in C , "Properties" is a feature that we can use in C # (or some other languages). The implementation of the implementation here is standard C , which is not expanded in any other language. Most libraries or compilers often make some extensions to C , just as we see in the managed C or C Builder, and some use ordinary SET and GET methods, these Can't be a true "property."
text:
First, let's take a look at what is "attribute." "Properties" look like a normal member variable in the class (or "field"), but it is accessible through a set / get method (or a READ / WRITE method). The actual member variable.
For example, if I have a class A and a "attribute" count, I can write the following code:
A foo;
Cout << foo.count;
COUNT actually called a GET function and returned the member variable value we wished. The most advantageous benefit of using "attribute" instead of directly using member variables is that you can control this "property" is read-only (you can only read its values without changing its value), write only, or can Read can be written. Let's implement it together:
We hope to achieve the following usage:
INT i = foo.count; // - actually call the GET function to get the value of the actual member variable -
foo.count = i; // - A SET function will actually set the value of the actual member variable -
Therefore, it is clear that we need to overload the "=" operator to set the "property" value, but also handle the "Properties" return type (you can see a little later).
We will implement a class, named Property, which will behave like a "attribute", its structure is as follows:
Template
Class Property {}
This type of template will behave as "attributes" we need. Container is a class of class (later we call "capacity class"), this class is the class that contains the actual member variable to be implemented as "Properties", access the set / get method of this variable and the "Properties" that is displayed. . ValueType is the type of actual member variable inside the capacity class (also the type of "Properties"), NPROPTYPE indicates the "Properties" category: "Read", "write" or "read and write".
We also need to set a set of pointers, pointing to the SET and GET methods of the container class-specific member variable, but also overload "=" operators, so that "attributes" can express like a variable. Let's take a look at the full program of the Property class.
#define r_only 1
#define Write_only 2
#define read_write 3
Template
Class Property
{
PUBLIC:
Property ()
{
m_cObject = null;
Set = null;
Get = NULL;
}
// - this to set a pointer to the class what contain the // Property -
Void setContainer (Container * COBject)
{
M_CObject = COBJECT;
}
// - set the set member function That Will Change The Value -
Void Setter (ValueType Value)
{
IF (NPROPTYPE == Write_Only) || (npropType == Read_Write))
Set = pset;
Else
Set = null;
}
// - set the get member function tria Will Retrieve The Value -
Void getter (ValueType (Container :: * Pget) ())
{
if ((nPropType == READ_ONLY) || (nPropType == READ_WRITE))
Get = pget;
Else
Get = NULL;
}
// - overload the '=' sign to set the value using the set
//Member -
ValueType Operator = (const valuetepe & value)
{
Assert (m_cobject! = null);
Assert (set! = null);
(m_cobject -> * set) (Value);
Return Value;
}
// - to make possible to cast the property class to the the preoperabi
// Internal Type -
Operator valueetype ()
{
Assert (m_cobject! = null);
askERT (GET! = NULL);
Return (M_CObject -> * GET) ();
}
Private:
Container * m_cobject; // - Pointer to the module That
// Contains the Property -
VoID (container :: * set) (ValueType Value);
// - Pointer to set member function -
ValueType (Container :: * GET) ();
// - Pointer to get member function -
}
Let us come to a segment analysis program:
The following code puts the Container pointer to a valid object. This object is the object we have to add "Properties" (that is, the container class).
Void setContainer (Container * COBject)
{
M_CObject = COBJECT;
}
The following segment, set the pointer to the SET / GET member function of the container class. The only limit here is that the SET function must be a function with a parameter and return VOID, and the GET function must have a parameter and return to the value of the ValueType type.
// - set the set member function That Will Change The Value -
Void Setter (ValueType Value)
{
IF ((NPROPTYPE == Write_only) || (npropType == Read_Write) SET = Pset;
Else
Set = null;
}
// - set the get member function tria Will Retrieve The Value -
Void getter (ValueType (Container :: * Pget) ())
{
if ((nPropType == READ_ONLY) || (nPropType == READ_WRITE))
Get = pget;
Else
Get = NULL;
}
The following segment is first to be overloaded with the "=" operator, which calls the SET member function of the container class to implement assignment. Then define a conversion function, which returns the return value of the GET function, which makes the entire Property class to behave like a ValueType type member variable.
// - overload the '=' sign to set the value using the set member -
ValueType Operator = (const valuetepe & value)
{
Assert (m_cobject! = null);
Assert (set! = null);
(m_cobject -> * set) (Value);
Return Value;
}
// - to make possible to cast the property class to the the preoperabi
// Internal Type -
Operator valueetype ()
{
Assert (m_cobject! = null);
askERT (GET! = NULL);
Return (M_CObject -> * GET) ();
}
Let's take a look at how we use this Property class:
Just like the following code: The Proptest class implements a "property" called count. The value of this "property" is actually obtained from a private variable named m_ncount from a GET function and writes a change in this "Property" value back to m_ncount through the SET function. Get / set functions can be named any because they are passed to the Property class through their function addresses, just as you can see in the constructor of the PropTest class. "Property The initialization work made in the constructor of the PropTest class is necessary, only in this way ensures that the defined "property" can work normally. 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 Private: INT m_ncount; } Just like the following demonstration, you can use the count "attribute" as a normal member variable: int i = 5, j; PROPTEST TEST; Test.count = i; // - Call the set method - J = Test.count; // - Call the get method - If you want your "Properties" that you define is read-only, you can do this: Property If you want to write only, do this: Property Note: If you set the "property" to be read-only, try to override it, will cause an assertion. If "attribute" is written only and you try to read it, the same situation will happen. to sum up: This article describes how to implement a "attribute" in the C class using standard C features. Of course, calling the SET / GET function directly is higher than using the "Properties", because you want to use Properties, you must instantiate a Property class for each "property" of the class. Original article: http://www.codeguru.com/cpp_mfc/property.html