D language operator overload

xiaoxiao2021-03-06  42

The operator overload operator overload is reintegrating the meaning of a one-dollar or binary operator acting on a particular structure or class, and the reinleased operator is implemented as a member of the structure or class. By overloading, we only need to use the original syntax to get the results we want.

One yuan operator overload

Overloaded one yuan operator

Op opfunc -e opneg e Oppos ~ E OPCOM E Oppostinc E - OPPOSTDEC CAST (TYPE) E OPCAST

Assuming that the operator that can be overloaded is OP, the corresponding class or structural member function is named OPFUNC, the syntax:

OP a

was explained as:

a.opfunc ()

among them

A is a reference for class or structure.

Overload E and --E Because of the definition

e is equivalent to semantics (

E = 1), expression

e will be rewritten as (

E = 1), then apply operator overload according to this form. -

E The situation is similar to.

Example

Class a {int opneg ();

A a a;

-a; // Isometrically equivalent A.OPNEG ();

Class A {Int opneg (INT I);

A a a;

-a; // Is equivalent to A.Opneg (), this is an error

Overloading CAST (Type) e calls member functions

e.

Opcast (), and

The return value of opcast () is implicitly converted to

TYPE. Because you can't be overloaded based on the return value, you can only have one structure or class.

Opcast function. The heavy-duty transition operator does not affect the implicit transformation and can only be used for explicit transformation.

Struct a

{

INT opcast () {return 28;}

}

Void test ()

{

A a a;

Long i = cast (long) a; // i is set to 28L

Void * p = cast (void *) a; // error, does not implicitly convert Int as VOID *

INT j = a; / / error, can't implicit A is int

}

Binary operator overload

Overloaded binary operator

OP can be exchanged? opfunc opfunc_r yes opAdd opAdd_r - no opSub opSub_r * yes opMul opMul_r / no opDiv opDiv_r% no opMod opMod_r & yes opAnd opAnd_r | yes opOr opOr_r ^ yes opXor opXor_r << no opShl opShl_r >> no opShr opShr_r >>> no opUShr opUShr_r ~ no opcat opcat_r == yes OPEquals -! = yes Opequals - Yes opcmp -> = yes opcmp - = no opaddassign - - = no opsubassign - * = no opmulassign - / = no Opdivassign -% = no opmodassign - | = no oporassign - ^ = no opxorassign - << = no opshlassign - >> = no opshrassign - >>> = no opshrassign - ~ = no opcatassign - given a two The Yuan Kere Operator OP and its corresponding class or structural member function named opfunc and opfunc_r, then the following syntax:

A OP B

Will apply the following rules in order to decide to use that form:

Expressions are rewritten as the following two forms: a.opFunc (b)

B.opFunc_R (a)

If one of the A.OpFunc or B.opFunc_R function exists, the most appropriate form is selected from the application overload resolution. If the function exists, but the parameters do not match, it is considered an error. If the operator is exchangeable, try the following form: a.opfunc_r (b)

B.OpFunc (a)

If A or B is a structure or class reference, it is an error. (Translation: If the class or structure is not overloaded with the above operator, the corresponding operation cannot be performed.)

Example

Class a {int OpAdd (INT I);

A a a;

A 1; // Isometrically worth A.OpAdd (1)

1 a; // Isometrically worth A.OpAdd (1)

Class B {int OPDIV_R (INT I);

B B;

1 / b; // Equivalent to B.OPDIV_R (1)

Class a {int OpAdd (INT I);

Class B {Int opAdd_r (a a);}

A a a;

B B;

A 1; // Isometrically worth A.OpAdd (1)

A B; / / Equivalent to B.OpAdd_r (a)

B a; // Isometrically Price B.OpAdd_r (a)

Class A {Int opAdd (B); int OpAdd_r (b);}

Class B {}

A a a;

B B;

A b; // Isometrically worth A.OpAdd (b)

B A; // Isometrically a.opAdd_R (B)

Class A {Int opAdd (B); int OpAdd_r (b);}

Class B {Int opAdd_r (a a);}

A a a;

B B;

A B; / / Ambiguity: A.OpAdd (b) is also B.OpAdd_r (a)? B A; // Isometrically a.opAdd_R (B)

Overload == and! = These two operators are used

OPEquals () function. expression

(a == b) is rewritten as

a.opequals (b), and

(a! = b) was rewritten as

! "a.opequals (b).

Member function OPEquals () is part of the object, defined as:

INT OPEQUALS (Object O);

All kinds of objects have

OPEquals ().

If the structure does not declares the OPEQUALS () function, the contents of the two structures are compared to test the equal or not equal.

Heavy load <, <=,> and> = these comparison operators are used

OPCMP () function. expression

(A OP B) is rewritten as

(a.Opcmp (b) op 0). Exclusive operation is rewritten

(0 OP B.OPCMP (a)).

Member function opcmp () is part of Object, defined as:

INT OPCMP (Object O);

All kinds of objects have

OPCMP ().

If the structure does not declares an OPCMP () function, trying to compare the size of the two structures is an error.

Note: The comparison of the reference to the class should do this:

IF (a === null)

Instead:

IF (a == NULL)

The latter is converted to:

IF (a.Opcmp (null))

in case

OPCMP () is a virtual function, the call will fail (the translation: If A is null, call the virtual function opcmp () to use the action similar to * A, similar to the null pointer in C , naturally error. facts. On, all types of root Object have declared an OPCMP () function, so calling this function for class instances almost certainly fail.).

The principle also owns

Opequals () and

The two functions of OPCMP () are:

Sometimes testing is less than or greater than the test. For some objects, the test is less than or equal to it. For these objects, OPCMP (): Class A can be overloaded like this.

{

INT OPCMP (Object O)

{

askERT (0); // There is no meaning of comparison

Return 0;

}

}

Function call operator overload F () function call operator, (), can be named

OpCall's function is overloaded:

Struct f

{

Int opcall ();

INT OPCALL (INT X, INT Y, INT Z);

}

Void test ()

{F F;

INT I;

I = f (); // Equivalent to i = f.opcall ();

I = f (3, 4, 5); // Equivalent to i = a.opCall (3, 4, 5);

}

This method, structure or object can be used to express the same function.

Array operator overload

Heavy Duty Index Operator A [i] array index operator, [], can be named

OpIndex's function is overloaded, which can have one or more parameters. As for the argument to the array, you can declare named

Opindexassign's function is overloaded, which can have two or more parameters. The first parameter is the right value of the assignment expression.

Struct a

{

INT OPINDEX (Int I1, INT I2, INT I3); INT OPINDEXASSIGN (Int Value, INT I1, INT I2);

}

Void test ()

{A a;

INT I;

I = a [5, 6, 7]; // Equivalent to i = a.Opindex (5, 6, 7);

A [i, 3] = 7; // Is equivalent to A.OPIndexassign (7, I, 3);

}

This method, structure or object can be used to express like an array. (Translation: opApply ?? Why didn't mention ??)

Note: Currently, array index overloads cannot be used for the left value of OP =, or - operators.

Heavy Duty Slice Operator A [] and A [i .. J] The heavy-duty slice operator means overloading, for example

a [] and

A [i .. j] This expression is used.

Class A

{

INT OPSLICE (); // Reserved a []

INT OPSLICE (int X, int y); // Reserved A [I .. J]

}

Void test ()

{A a = new a ();

INT I;

I = a []; // Equivalent to i = a.opSlice ();

I = a [3..4]; // Equivalent to i = a.opSlice (3, 4);

}

The future direction '.', '&&', '||', '?:' and other minor operators can never become overloaded. The function name of the overload operator may change.

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

New Post(0)