D language class and interface

xiaoxiao2021-03-06  44

Object-oriented properties of class D come from class. The top of the class is the class Object. Object defines the minimum set of functions owned by each derived class and provides the default implementation for these features.

Class is the type of programmer definition. As an object-oriented language, D support object, support packaging, inheritance, and polymorphism. Class D Support Single inherits programming, and supports the interface. Class objects can only be used by reference.

Classs can be exported, which means that its name and non-private members will expose to external DLL or EXE.

Class declarations are defined as:

Class declaration:

Class flag [parent class {, interface class}] class procedure

father:

: Flag

Interface class:

Marker

Class Process Body:

{Class procedure statement}

Class Process Body Statement:

statement

Constructor

Destructor

Static constructor

Static destructor

Invillate

unit test

Class distributor

Class release

ClassDeclaration:

Class Identifier [Superclass {, InterfaceClass}] ClassBody

Superclass:

: Identifier

InterfaceClass:

Identifier

ClassBody:

{ClassbodyDeclarations}

ClassBodyDeclaration:

Declaration

Constructor

Destructor

StaticConstructor

StaticDestructor

Invariant

UnitTest

Classallocator

Classdeallocator

The composition of the class:

father

interface

Dynamic domain

Static domain

Types of

function

Static function

Dynamic function

Constructor

Destructor

Static constructor

Static destructor

Invillate

unit test

Dispenser

Liberator

Class definition:

Class foo

{

... member ...

}

Note that there is no 'after the end of the flag-defined end of the flag class;'. It is also not possible to declare the variables like this:

Class foo {} var;

It should be declared this:

Class foo {}

Foo var;

The domain members are always accessed by '.' Operators. There is no C '::' or '->' operator.

The D compiler has the order in which each domain is retrieved, so that the compiler is allowed to compress them to optimize the program in a manner defined. Therefore, the alignment statement, anonymous structure, and anonymity are not allowed to appear in the class because they rely on data arrangement. Consider the domain of local variables in the function to assign some of them into the register, other ideal distributions are saved into the stack frame. This gives the code designer to rearrange the code to enhance the freedom of readability, without having to force the code designer to arrange the relevant domain based on the machine's optimization rules. Structure / joint provides an explicit control domain distribution capability, but this is not a matter of class.

The parent class is inherited from the parent class. If not specified, it inherits Object. Object is the root of the Class D hierarchy system.

Constructor

Constructor:

THIS () statement block

Constructor:

this () blockstatement

All members are initialized to its default initial value of its corresponding type, usually the integer is initialized to zero, and the floating point number is initialized to nan. This prevents that the discovered error is caused by ignoring the initialization a member in a constructor. In the class definition, you can use a static initial value instead of the default value:

Class ABC

{

INT A; // a default initial value is 0

Long b = 7; // b The default initial value is 7

Float f; // f's default initial value is nan

}

Static initialization is done before calling the constructor.

The constructor is a function called this, it does not return the value:

Class foo

{

THIS (INT X) // Declaration FOO Construction Function

{...

}

this ()

{...

}

}

Base class construct

Super Call the constructor of the base class to complete:

Class a {this (int y) {}}

Class B: a

{

Int J;

this ()

{

...

Super (3); // Call the base class constructor a.THIS (3)

...

}

}

The constructor can also call other constructor in the same class to share universal initialization code:

Class C

{

Int J;

this ()

{

...

}

THIS (INT i)

{

THIS ();

J = i;

}

}

If the constructor is not passed

THIS or

Super call constructor, and the base class has a constructor, the compiler will automatically insert one at the beginning of the constructor.

Super ().

If the class does not construct a function, the base class has a constructor, then the default constructor is:

THIS () {}

This will be implicitly generated by the compiler.

The structure of the class object is flexible, but there are some restrictions:

The constructor is illegal: this () {this (1);}

THIS (INT i) {this ();} // illegal, constructor loop call

If the constructor is called in a constructor, you can only call once constructor in any execution path of this constructor: this () {a || super ();} // illegal

THIS () {this (1) || super ();} // ok

this ()

{

for (...)

{

Super (); // illegally, located within the cycle

}

}

Explicitly or implicitly referenced by the constructor. The constructor cannot be called after the label (the purpose of doing this is to make the preamble condition of GOTO is easy to complete). Example of class object

New Expression Create:

A a = new a (3);

In this process, follow these steps:

Assign a storage space for an object. If it fails, it will not return null and will throw an OutofMemoryException. Therefore, no longer need to write a lengthy and boring NULL reference defense code. Use the statically static initialization of "raw data" in the class definition. Assign a pointer to the virtual function table. This ensures that the class that calls the constructor is fully formed. This operation is equivalent to copying the static version of the object to the space of the newly assigned object, but the higher compiler will optimize this method. If the constructor is defined for the class, the constructor of the matching parameter list is called. If the type of non-variable is turned, the invariant call is called after the constructor call.

Destructor

Destructor:

~ this () statement block

DESTRUCTOR:

~ this () blockstatement

The destructor will be called when the object is deleted by the garbage collection program. The syntax is as follows:

Class foo

{

~ this () // foo destructor

{

}

}

Each class can only have a destructuring function, and the destructor has no parameters, no feature. It is always virtual functions.

The role of this structure is to release any resources held by the object.

The program can explicitly notify the garbage collection program is not referenced to an object (using the delete expression), then the garbage collection program will call the destructor immediately and put the memory occupied by the object back to the free storage area. The destructor must not be called twice.

The destructive function of the parent class is automatically called when the parsing function runs. The destructive function of the parent class cannot be explicitly invoked.

When the garbage collection program calls an object's destructive function, and this object contains references to the garbage collection object, then these references become invalid. This means that the destructor cannot reference the child object. This rule does not apply to the AUTO object or the object that releases the expression release.

Garbage collection procedures cannot guarantee that the destructor is called for all non-reference objects. And the garbage collection procedure does not guarantee the relative order of the call. Objects referenced from the data segment will not be collected by the garbage collection program.

Static constructor

Static constructor:

STATIC this () statement block

StaticConstructor:

Static this () blockStatement

Static constructor performs initialization before the main () function gets control. The static constructor is used to initialize the static class members that their values ​​cannot be compiled.

The static constructor in other languages ​​is designed to initialize using members. The problem does not be able to accurately control the order of code execution. E.g:

Class foo

{

Static int A = B 1;

Static Int B = a * 2;

}

What is the finals A and B? What is initialized in order? What is the value of A and B in initialization? Is this a compilation error? Or or it is an error? There is also a case where it is not so confusing is that a single initialization is still static or dynamic.

D makes all this simple. All member initialization must be determined at compile, so there is no problem-dependent problem, and it is impossible to read a value that is not initialized. Dynamic initialization is performed by a static constructor and implemented using syntax STATIC THIS ().

Class foo

{

Static int A; // By default initialization is 0

Static Int B = 1;

Static int C = B a; / / error, not constant initialization

Static this () // Static constructor

{

A = B 1; // a is set to 2

B = a * 2; // B is set to 4

}

}

Static this () will be called by the startup code

Main () is called before. If it returns (no exceptions), the static destructuring function will be added to the list of functions that will be called when the program is terminated. The parameter list of the static constructor is empty.

The disadvantage of the current static constructor is that the order of calling them is unfained. Therefore, temporary, the static constructor is dependent on the order of declaration. This issue will be resolved in future versions.

Static destructor

Static destructor:

STATIC ~ THIS () statement block

StaticDestructor:

Static ~ this () blockStatement

Static destructor is defined as a grammatical form

Special Static Function of Static ~ this ().

Class foo

{

Static ~ this () // Static destructor

{

}

}

The static destructor is called when the program is terminated, but this only occurs when the static constructor is successfully executed. The parameter list of the static destructuring function is empty. The static destructor is called in reverse sequencing in accordance with the static constructor.

Class invariant

Class invariant:

INVARIANT statement

ClassIntinvariant:

Invariant BlockStatement

Class invariant is used to specify that the class must always be true features (except when executing member functions). For example, a class representing the date may have an invariant - DAY must be between 1..31, and HOUR must be between 0..23:

Class Date

{

Int day;

Int Hour;

Invariant

{

ASSERT (1 <= day && day <= 31);

ASSERT (0 <= Hour && Hour <24);

}

}

Class invariance is a contract, which must be true assertion. When the class constructor is executed, when the class's destructor is executed, the invariat is performed before the PUBLIC or Exported member function is executed, or when the public or exported member function is complete. The code in the invariant should not call any non-static public class members, regardless of direct or indirect. If you do, you will cause a stack overflow because the invariable will be called unlimited.

Class foo

{

Public void f () {}

Private void g () {}

Invariant

{

f (); // error, can not call public member functions in an invariant

g (); // ok, g () is not public

}

}

can use

Assert () check the invariance of the object, for example:

Date mydate;

...

askERT (MyDate); / / Check the invariance of class DATE

If the invariant check failed, one will throw a

Invariantexception is abnormal. Class invariance will be inherited, that is, any type of invariance implitably contains the invariance of its base class.

Each class can only have a class invariant.

When compiling generating published version, the invariant check code is not generated so that the program will run at the highest speed.

unit test

unit test:

UnitTest statement block

UnitTest:

UnitTest BlockStatement

Unit testing is a series of test cases used to test whether a class works fine. Ideally, the unit test should run over again at each time. Make sure that the best way to do this is to put them in the same kind of code to the category implementation code, maintained together.

D's class can have a special member function called:

UnitTest

{

... test code ...

}

All classes in the program will be called before static initialization, and the main function call is called before. A compiler or linker switch will remove the test code from the final build.

For example, assume that a class SUM is used to calculate two worth:

Class Sum

{

INT Add (int x, int y) {return x y;}

UnitTest

{

ASSERT (Add (3, 4) == 7);

ASSERT (add (-2, 0) == -2);

}

}

Class distributor

Class allocator:

NEW parameter list statement block

ClassAllocator:

New Parameterlist BlockStatement

A class member function with the following form is called a class distributor:

NEW (uint size)

{

...

}

If the type of the first parameter is UINT, the class allocator can have any number of parameters. You can define multiple class allocators for classes, select the appropriate function by overloading the resolution rules through a universal function. Perform a New expression:

NEW foo;

And when the foo is a class with the dispenser, the dispenser will be called, and the first parameter is set to assign a memory size required to byte in one instance. The dispenser must allocate the memory and return one

Void * pointer. If the assignment fails, it does not have to return one

NULL, but a must have throw an exception. If the dispenser has more than one parameter, the remaining parameters will be

NEWEXPRESSION

The brackets after New:

Class foo

{

this (char [] a) {...}

NEW (uint size, int x, int y)

{

...

}

}

...

New (1, 2) foo (a); // Call New (foo.size, 1, 2)

If you do not specify a class distributor, the derived class will inherit the class allocator of the base class.

See also the explicit class instance assignment.

Class release

Class Release: DELETE Parameter List Statement

Classdeallocator:

Delete Parameterlist BlockStatement

A class member function with the following form is called a class release:

Delete (void * p)

{

...

}

Some types of release are only one type

VOID * parameters. A class can only have a class release. Perform a delete expression:

delete f;

And f is an example of a class with a liberator, if the class has a patterned function, the destructor is called, and then the release is called, and a pointer to the class instance is passed to the release. Release memory is the responsibility of the release.

If not specified, the derived class will inherit all releases of the base class.

See Explicit class instance assignment.

The AUTO AUTO class is a class with the AUTO characteristics, as follows:

Auto class foo {...}

The Auto feature is inherited, so any classes inherited from the AUTO class are auto.

References to the Auto class can only appear as a function of local variables, and this reference must be declared as Auto:

Auto class foo {...}

Void func ()

{

Foo f; // Error, reference to the AUTO class must be Auto

Auto foo g = new foo (); // correct

}

When an AUTO class is quote out of the scope, it will automatically call its destructor (if any). This behavior occurs even because of an abnormality.

interface

Interface declaration:

Interface sign

Interface Mark: Parent Interface Interface

Parent interface:

Marker

Flag, parent interface

Interface:

{Declaration definition}

InterfaceDeclaration:

Interface Identifier InterfaceBody

Interface Identifier: SuperInterfaces InterfaceBody

Superinterfaces

Identifier

Identifier, SuperInterfaces

InterfaceBody:

{Decldefs}

The interface describes a list of functions that must be implemented from the interface derived. A reference to a class derived from an interface can be converted to a reference to this interface. The interface corresponds to the interface of the object exposed to the operating system, such as the COM / OLE / ACTIVEX of Win32.

The interface cannot be derived from the class, and can only be derived from other interfaces. The class cannot be derived from one interface multiple times.

Interface D

{

Void foo ();

}

Class A: D, D / / Error, multiple interfaces

{

}

An instance of the interface cannot be created.

Interface D

{

Void foo ();

}

...

D = new d (); // error, unable to create an instance of the interface

Interface member functions cannot be implemented.

Interface D

{

Void bar () {} // error, not allowed

}

The class of inheritance interface must implement all functions in the interface:

Interface D

{

Void foo ();

}

Class A: D

{

Void foo () {} // ok provides implementation

}

Class B: D

{

INT foo () {} // error, no void foo () implementation

}

The interface can be inherited, where the function can be rewritten:

Interface D

{

INT foo ();

}

Class A: D

{

INT foo () {return 1;}

}

Class B: a

{

INT foo () {return 2;}}

...

B b = new b ();

B.foo (); // Return 2

D = (d) b; // ok, because B inherits a D implementation

D.foo (); // Return 2

The interface can be re-implemented in the derived class:

Interface D

{

INT foo ();

}

Class A: D

{

INT foo () {return 1;}

}

Class B: a, d

{

Int foo () {return 2;}

}

...

B b = new b ();

B.foo (); // Return 2

D d = (d) b;

D.foo (); // Return 2

A a = (a) b;

D d2 = (d) a;

D2.foo (); // Return 2, although it is a D, not B D

If the class wants to re-implement the interface, all functions of the interface must be reinforced, and cannot inherit from the parent class:

Interface D

{

INT foo ();

}

Class A: D

{

INT foo () {return 1;}

}

Class B: a, d

{

} // Error, interface D does not foo ()

A variant of the COM interface interface is a COM interface. According to the design, the COM interface is mapped directly to the Windows COM object. Any COM object is represented by a COM interface, and any D object with a COM interface can be used by an external COM client.

Press the definition, the COM interface is derived from the std.c.windows.com.iunknown interface. The COM interface is different from the ordinary D interface in:

It derived from the std.c.windows.com.iunknown interface. It can't be the parameter of deleteExpression. The reference cannot be transformed into the encapsulated class object, and it cannot be transformed down to the interface from which it is derived. In order to achieve this, a suitable queryinterface () method must be implemented in accordance with the standard COM style.

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

New Post(0)