[Reposted] Implementation of Class C # Properties in BCB Declaration Syntax

xiaoxiao2021-03-06  69

[Reposted] Goldroc's column to implement class C # attribute declaration syntax in BCB

Use macro command to transform BCB - Implement class C # attribute declaration syntax in BCB

Primer

Hailing procedures, hi BCB (Borland C Builder). See the property statement of C # on one day, and feel refreshed. Thereafter, there will be, and it is completely organized, and the name of the crown article is used. The husband is like a good and bcb, or can be beneficial. If it is, it is a purpose.

Background Description - Macro's historical position

After the object-oriented C language is launched, an extremely important macro command once in C seems to be rarely used. Even C Master Bjarne Stroustrup is also said in his classic C tutorial "THE C Programming Language" said: "About Hong's first rule is: Never use it, unless you have to do this. Because it will The compiler sees the text of the program before resending these text. "Even the most used defined constants used in C has a new keyword const, plus other inline, template, enum, namespace mechanism, etc. In order to use many traditional ways of use of the pretreatment structure.

However, Bjarne Stroustrup also admits that we can design your private language using macros. As long as it makes our work simplify, it is a useful macro.

"You can design your own private language", what does it mean for us? How do I use it to transform existing languages ​​to simplify our work? Of course, the so-called simplification is inextricably complicated. So as long as it is an original grammatical, we can use macro to simplify it.

A good typical is the property declaration syntax in the BCB.

Background Description - BCB and C # properties Declaration Syntax

To declare an attribute in the class declaration of the BCB, you must first declare a store of a property data - a data member. Of course, in general, it is declared in private partial. Then there are some other operations when reading or writing properties, then declare the method of reading or writing attributes. Generally speaking, in order to ensure the legal line of data, there is often at least one write property method. Finally, I have to release it in public or __publish (components) to be visible by the user of the class.

Let's take a look at the specific code.

Suppose a girl CGIRL, has a beautiful index property prettiness, and the range is 0-3.0: its ugly is incomparable; 1: Malays and tiger; 2: Decorated Tiger 3: Drama Allure. So all have to write this in BC:

Header file cgirl.h

Class cgirl

{

PUBLIC:

__property int prettiness = {read = fgetprettiness, Write = fsetprettiness};

... // (Slight to other public members)

Private:

Int fprettiness;

... // (Slightly remove other private data members)

INT __FASTCALL FGETPRETTINESS ();

Void __fastcall fsetprettiness (int vprettiness)

... // (Some of the following other private methods)

}

Code file CGIRL.CPP

INT __fastcall cgirl :: fgetprettiness ()

{

Return fPRETTINESS;

}

Void __fastcall cgirl :: fsetprettiness (int vPrettiness)

{

IF (vPrettiness <= 3 && vPrettiness> = 0)

FPRETTINESS = V fprettiness;

......

For simple classes, this definition may not be too trouble. The definition of the attribute can be clear. But if the class is slightly complicated - the specific point is if it is a 1000-line class? (Sweating) The result is often turned back in the Nobi Code, which is the definition of reading and writing methods related to a property.

Now, after the release of Microsoft .NET, .NET Framework suddenly became the most popular stuff. It hits it in unstoppable potential. Moreover, Microsoft has told the SUN Java, nor does it take care of the progral of the programming language, and a new language is added in Visual Studio. I don't want me to say that everyone knows - pair is it: C #, another and C syntax very similar language.

There is too much story for .NET and C #, it is impossible to say it here. However, C #'s grammar for attribute declarations has left a deep impact on the author. This is precisely what we are concerned about today. Take a look at the C # property declaration syntax. As an example in the CGIRL class above, it is possible to look like this:

Class cgirl

{

Private int fprettiness;

Public int prettiness // Define properties

{

Get // read property method

{

Return fPRETTINESS;

}

SET // Write Properties Method

{

IF (Value <= 3 && value> = 0)

FPRETTINESS = VALUE;

}

}

}

I don't need to say more, and it is very obvious.

Below, let's take a look at how to make the complicated property declare syntax as C # simply through the macro command. This is not a trick, but it is a little fine.

Technical basis - macro definition grammar

First, we have to understand the format of the macro: #define <名> [Expand Content]

In fact, this thing is almost what can't do, but if you bring it on the parameters:

// Macro definition format with parameters

#define

For example, a statement with a ginseng macro: #define writen (a) cout << a << endl

In the code, if you write: WRITEN ("use macro command, transform C builder");

Then, after the macro is expanded, it will become like this: cout << "Clever use macro command, transform C builder" << ENDL;

This is the expansion of the envelope, is not complicated. In order to turn the properties of the BCB into C #, we also need to know two operators: / and ##.

1, / Operator: When a macro defined extension content is more than a line of connectors.

If you want to write a macro definition, add it on the tail. Such as:

#define Title uses a macro /

Order, transform C Builder

Equivalent to:

#define Title uses macro command to transform C Builder

2, ## operator: Parameter extension connector.

It can connect the previous content and parameters into a whole without intervals. Let's take a look at the example:

Define a macro: #define var (i, j) (i ## j)

Then write this in the code: VAR (x, 6), it will be expanded to x6. Using this feature we can modify a given macro parameter in order to adapt to our requirements. Technology implementation - start retrofit BCB

The foundation is so much, then take a look at what needs to be used to transform BCB.

First, determine the name of the macro, here is a macro name for Temporary.

Next, determine the parameters of the macro.

Our destination should make the macro the use of the symptoms of the C #, so how many macros should be used like this:

Property

(

Property visibility attribute type property name

{

get

{

// read attribute code

}

set

{

// write attribute code

}

}

)

However, although the pseudo code above is closest to the C # syntax, it cannot define suitable macros. The reason is that some important parameter elements needed by the macro cannot be separated from the overall code. The so-called important parameter elements are "visibility", "attribute type", "element", "read property code part", "Write Properties section", as described above. The above pseudo code starts from "visibility" from "attributes until the last brace is a whole, becoming a parameter. This naturally cannot be expanded correctly. We should separate these five important elements into one parameters, and the principle is of course, the better the pseudo code above:

Property

(

Attribute visibility, attribute type, property name,

get

{

// read attribute code

}

,

set

{

// write attribute code

}

)

This reaches the requirements of each element and independently becomes a macro parameter.

Then, we will design this macro on the form of the above usage.

First give each element of each element, it is:

Property visibility pregion

Property Type PTYPE

Attribute name PNAME

Read attribute code PgetMethod

Write properties code PsetMethod

Remember two method functions required to declare a property in BCB, respectively, read and write. A fixed function name must be used in the macro definition, and must be related to the property name. This way we are set to form a FGET and FSET in front of the attribute name to form a read / write method function, and the parameters of the write method (the new value of the corresponding attribute) are always Value (as in C #).

Definition in the macro:

// Read method function

PTYPE __FASTCAL FGET ## PNAME () PgetMethod

// write method functions

Void __fastcall fset ## pname (ptype value) PsetMethod

Don't forget that there is an attribute publishing statement:

__property ptype pname = {read = fget ## PNAME, WRITE = fset ## PNAME};

To finish, the statement of the macro finally turned to the following:

Property (Pregion, Ptype, PNAME, PgetMethod, PsetMethod) /

PRIVATE: /

Ptype Fget ## PNAME () /

PgetMethod /

Void Fset ## PName (Ptype Value) /

PsetMethod /

PREGION: /

__property ptype PNAME = {/

Read = fget ## PNAME /

, Write = fset ## PNAME /

}

Note: In the use of the macro, the read or write method functions also have a GET or SET identifier, and they must be blocked, otherwise it is not possible to form a complete function implementation by adding PgetMethod or PsetMethod to the function declaration after the function declaration.

Shield GET or SET: #define get by the following two macro declarations

#define set

Here, this macro definition is basically successful. However, since the attribute may have read-only, only written or no read method functions (many attributes can only read the value of the member data, no additional code) is different, we also need another few Macros can be applied to these situations. See the specific code.

Finally, several places worth special attention to using such a macro:

1. Pay attention to the comma of each macro parameter, especially between GET and SET methods.

2, pay attention to the GET and SET methods implementation cannot be reversed.

Complete implementation - specific code

GOLDROC OPUS / / /

// Attribute definition macro (for C Builder)

// Description: Insect the attribute statement in the C #

/ / (In header file)

/ / Define Readable Writing Properties: Property (Attribute Visibility, Property Type, Property Name, Read Properties Code, Write Properties)

// Define read-only properties: Property_ReadOnly (property visibility, attribute type, property name, read properties code)

// Define only write properties: proty_writeonly (property visibility, attribute type, property name, write property code)

// Define the property macro that does not need to read the method: Property_Direct_read (attribute visibility, attribute type, property name, data corresponding to the property), write attribute code)

// Define read-only property macros not need to read method: Property_Direct_read (attribute visibility, attribute type, property name, data corresponding to attribute)

//

/

// The following macro definitions general rules are as follows:

// Place the member variable of the record attribute data in private, name to F

/ / Place the function of the member variable of the attribute data in private, name to FGET or FSET in previous member variable name

// Ring is called Value

// such as: Property INT LEFT

// Property

// (public, int, left,

// Get

// {

// Return_Left; // Prepare the current value of the attribute before the attribute

//}

//, // Note this comma can not be lost! ! !

// set

// {

// _left = value; // The new value is Value

//}

//

//

// Note: GET and SET methods cannot be reversed!

//

// read-only attribute INT LEFT

// Property_Readonly

// (public, int, left,

// Get

// {

// Return_Left; // Prepare the current value of the attribute before the attribute

//}

//

/ / -------------------------------------------------------------------------------------------- ---------------------------

/ / -------------------------------------------------------------------------------------------- ---------------------------

#ifndef proty_macroh

#DEFINE PROPERTY_MACROH

/ / -------------------------------------------------------------------------------------------- --------------------------- # Define get / * get * /

#define set / * set * /

#define Property (Pregion, Ptype, PName, PgetMethod, PsetMeth /

PRIVATE: /

Ptype Fget ## PNAME () Const /

PgetMethod /

Void Fset ## PName (const ptype & value) /

PsetMethod /

PREGION: /

__property ptype PNAME = {/

Read = fget ## PNAME /

, Write = fset ## PNAME /

}

// read-only property macro

#define property_readonly (Pregion, Ptype, PNAME, PgetMethod) /

PRIVATE: /

Ptype Fget ## PNAME () Const /

PgetMethod /

PREGION: /

__property ptype PNAME = {/

Read = fget ## PNAME /

}

// write only the property macro

#define Property_Writeonly (Pregion, Ptype, PName, PsetMethod) /

PRIVATE: /

Void Fset ## PName (const ptype & value) /

PsetMethod /

PREGION: /

__property ptype PNAME = {/

Write = fset ## PNAME /

}

// Do not need to read the property macro

#define property_direct_read (Pregion, Ptype, PNAME, PDATA, PSETMETHOD) /

PRIVATE: /

Void Fset ## PName (const ptype & value) /

PsetMethod /

PREGION: /

__property ptype PNAME = {/

Read = PDATA /

, Write = fset ## PNAME /

}

// Do not need reading method read-only macro

#define property_direct_readonly (Pregion, Ptype, PNAME, PDATA) /

PREGION: /

__property ptype PNAME = {/

Read = PDATA /

}

#ENDIF

/ / -------------------------------------------------------------------------------------------- ---------------------------

(The above code is debugged in BCB6)

In this way, save the above code as a header file, such as Property_Macro.h. In the future, in your code #include, you can include this header file. According to the same principle, we can even transform the entire class statement of BCB into class C #, which is no longer educated, readers can try themselves.

Now let's try to write "C #" in the BCB.

转载请注明原文地址:https://www.9cbs.com/read-119319.html

New Post(0)