Menu English Ukrainian russian Home

Free technical library for hobbyists and professionals Free technical library


Lecture notes, cheat sheets
Free library / Directory / Lecture notes, cheat sheets

Computer science and information technology. Compatibility of object types (lecture notes)

Lecture notes, cheat sheets

Directory / Lecture notes, cheat sheets

Comments on the article Comments on the article

Table of contents (expand)

LECTURE No. 12. Methods

1. Methods

A method declaration inside an object type corresponds to a forward method declaration (forward). Thus, somewhere after an object type declaration, but within the same scope as the scope of the object type declaration, a method must be implemented by defining its declaration.

For procedural and functional methods, the defining declaration takes the form of a normal procedure or function declaration, with the exception that in this case the procedure or function identifier is treated as a method identifier.

For constructor and destructor methods, the defining declaration takes the form of a procedure method declaration, with the exception that the reserved word procedure is replaced by the reserved word constructor or destructor.

The defining method declaration may, but need not, repeat the list of formal parameters of the method header in the object type. In this case, the method header must exactly match the header in the object type in order, types, and parameter names, and in the return type of the function result if the method is a function.

The defining description of a method always contains an implicit parameter with the identifier Self, corresponding to a formal variable parameter that has an object type. Within a method block, Self represents the instance whose method component was specified to invoke the method. Thus, any changes to the values ​​of the Self fields are reflected in the instance.

The scope of an object type bean identifier extends to blocks of procedures, functions, constructors, and destructors that implement methods of that object type. The effect is the same as if a with statement of the following form were inserted at the beginning of the method block:

with self do

begin

...

end;

Based on these considerations, the spelling of component identifiers, formal method parameters, Self, and any identifier introduced into the executable part of the method must be unique.

If a unique method identifier is required, then the qualified method identifier is used. It consists of an object type identifier followed by a dot and a method identifier. As with any other identifier, a qualified method identifier may optionally be preceded by a package identifier and a period.

Virtual Methods

Methods are static by default, but except for constructors, they can be virtual (by including the virtual directive in the method declaration). The compiler resolves references to static method calls during the compilation process, while calls to virtual methods are resolved at run time. This is sometimes called late binding.

If an object type declares or inherits any virtual method, then the variables of that type must be initialized by calling a constructor before calling any virtual method. Thus, an object type that describes or inherits a virtual method must also describe or inherit at least one constructor method.

An object type can override any of the methods it inherits from its parents. If a method declaration in a child specifies the same method identifier as a method declaration in the parent, then the declaration in the child overrides the declaration in the parent. The scope of an overriding method expands to the scope of the child in which the method was introduced, and will remain so until the method identifier is overridden again.

Overriding a static method is independent of changing the method header. In contrast, a virtual method override must preserve the order, parameter types and names, and function result types, if any. Moreover, the redefinition must again include the virtual directive.

Dynamic Methods

Borland Pascal supports additional late-bound methods called dynamic methods. Dynamic methods differ from virtual methods only in the way they are dispatched at runtime. In all other respects, dynamic methods are considered equivalent to virtual methods.

A dynamic method declaration is equivalent to a virtual method declaration, but the dynamic method declaration must include the dynamic method index, which is specified immediately after the virtual keyword. The index of a dynamic method must be an integer constant between 1 and 656535 and must be unique among the indexes of other dynamic methods contained in the object type or its ancestors. For example:

procedure FileOpen(var Msg: TMessage); virtual 100;

An override of a dynamic method must match the order, types, and names of the parameters, and exactly match the result type of the function of the parent method. The override must also include a virtual directive followed by the same dynamic method index that was specified in the ancestor object type.

2. Constructors and destructors

Constructors and destructors are specialized forms of methods. Used in connection with the extended syntax of the New and Dispose standard procedures, constructors and destructors have the ability to place and remove dynamic objects. In addition, constructors have the ability to perform the required initialization of objects containing virtual methods. Like all methods, constructors and destructors can be inherited, and objects can contain any number of constructors and destructors.

Constructors are used to initialize newly created objects. Typically, initialization is based on the values ​​passed to the constructor as parameters. A constructor cannot be virtual because the dispatch mechanism of a virtual method depends on the constructor that initialized the object first.

Here are some examples of constructors:

constructor Field.Copy(var F: Field);

begin

Self := F;

end;

constructor Field.Init(FX, FY, FLen: integer; FName: string);

begin

X := FX;

Y := FY;

GetMem(Name, Length(FName) + 1);

Name^ := FName;

end;

constructor TStrField.Init(FX, FY, FLen: integer; FName: string);

begin

inherited Init(FX, FY, FLen, FName);

Field.Init(FX, FY, FLen, FName);

GetMem(Value, Len);

Value^ := '';

end;

The main action of a constructor of a derived (child) type, such as the above TStr Field. Init is almost always a call to the appropriate constructor of its immediate parent to initialize the inherited fields of the object. After executing this procedure, the constructor initializes the fields of the object that belong only to the derived type.

Destructors are the opposite of constructors and are used to clean up objects after they have been used. Normally, cleanup consists of removing all pointer fields in the object.

Note

A destructor can be virtual, and often is. A destructor rarely has parameters.

Here are some examples of destructors:

destructor Field Done;

begin

FreeMem(Name, Length(Name^) + 1);

end;

destructor StrField.Done;

begin

FreeMem(Value, Len);

Field Done;

end;

The destructor of a child type, such as the TStrField above. Done, typically first removes the pointer fields introduced in the derived type, and then, as a last step, calls the appropriate collector-destructor of the immediate parent to remove the object's inherited pointer fields.

3. Destructors

Borland Pascal provides a special type of method called a garbage collector (or destructor) for cleaning up and deleting a dynamically allocated object. The destructor combines the step of deleting an object with any other actions or tasks required for that type of object. You can define multiple destructors for a single object type.

The destructor is defined along with all other object methods in the object's type definition:

type

Temployee = object

Name: string[25];

Title: string[25];

Rate: Real;

constructor Init(AName, ATitle: String; ARate: Real);

destructor Done; virtual;

function GetName: String;

function GetTitle: String;

function GetRate: Rate; virtual;

function GetPayAmount: Real; virtual;

end;

Destructors can be inherited and they can be either static or virtual. Since different finalizers tend to require different types of objects, it is generally recommended that destructors are always virtual so that the correct destructor is executed for each type of object.

The reserved word destructor does not need to be specified for every cleanup method, even if the object's type definition contains virtual methods. Destructors really only work on dynamically allocated objects.

When a dynamically allocated object is cleaned up, the destructor performs a special function: it ensures that the correct number of bytes are always freed in the dynamically allocated memory area. There can be no concern about using a destructor with statically allocated objects; in fact, by not passing the object's type to the destructor, the programmer deprives an object of that type of the full benefits of dynamic memory management in Borland Pascal.

Destructors actually become themselves when polymorphic objects must be cleared and when the memory they occupy must be deallocated.

Polymorphic objects are those objects that have been assigned to a parent type due to Borland Pascal's extended type compatibility rules. An instance of an object of type THourly assigned to a variable of type TEmployee is an example of a polymorphic object. These rules can also be applied to objects; a pointer to THourly can freely be assigned to a pointer to TEmployee, and the object pointed to by that pointer will again be a polymorphic object. The term "polymorphic" is appropriate because code that processes an object "doesn't know" exactly at compile time what type of object it will eventually need to process. The only thing it knows is that this object belongs to a hierarchy of objects that are descendants of the specified object type.

Obviously, the sizes of the object types are different. So when it comes time to clean up a heap-allocated polymorphic object, how does Dispose know how many bytes of heap space to free? At compile time, no information about the object's size can be extracted from a polymorphic object.

The destructor solves this puzzle by referring to the place where this information is written - in the TCM implementation variables. Each TBM of an object type contains the size in bytes of that object type. The table of virtual methods of any object is available through the hidden parameter Self, sent to the method when the method is called. A destructor is just a type of method, and so when an object calls it, the destructor gets a copy of Self on the stack. Thus, if an object is polymorphic at compile time, it will never be polymorphic at run time due to late binding.

To perform this late-bound deallocation, the destructor must be called as part of the extended syntax of the Dispose procedure:

Dispose(P, Done);

(A call to the destructor outside of the Dispose procedure does not deallocate any memory at all.) What is really happening here is that the garbage collector of the object pointed to by P is executed as a normal method. However, once the last action is complete, the destructor looks up the size of its type's implementation in the TCM and passes the size on to the Dispose procedure. The Dispose procedure terminates the process by deleting the correct number of bytes of the heap space that (the space) previously belonged to P^. The number of bytes to be freed will be correct regardless of whether P pointed to an instance of type TSalaried, or whether it pointed to one of the child types of type TSalaried, such as TCommissioned.

Note that the destructor method itself can be empty and perform only this function:

destructorAnObject.Done;

begin

end;

What is useful in this destructor is not the property of its body, however, the compiler generates epilogue code in response to the destructor reserved word. It's like a module that doesn't export anything, but does some invisible work by executing its initialization section before starting the program. All action takes place behind the scenes.

4. Virtual Methods

A method becomes virtual if its object type declaration is followed by the new reserved word virtual. If a method in a parent type is declared as virtual, then all methods with the same name in child types must also be declared virtual to avoid a compiler error.

The following are the objects from the example payroll, properly virtualized:

type

PEmployee = ^TEmployee;

Temployee = object

Name, Title: string[25];

Rate: Real;

constructor Init(AName, ATitle: String; ARate: Real);

function GetPayAmount: Real; virtual;

function GetName : String;

function GetTitle : String;

function GetRate : Real;

procedure Show; virtual;

end;

PHourly = ^THourly;

THourly = object(TEmployee);

Time: Integer;

constructor Init(AName, ATitle: String; ARate: Real; Time: Integer);

function GetPayAmount: Real; virtual;

function GetTime: Integer;

end;

PSalaried = ^TSalaried;

TSalaried = object(TEmployee);

function GetPayAmount: Real; virtual;

end;

PCommissioned = ^TCommissioned;

TCommissioned = object(Salaried);

Commission: Real;

Sales Amount : Real;

constructor Init(AName, ATitle: String; ARate,

ACommission, ASalesAmount: Real);

function GetPayAmount: Real; virtual;

end;

A constructor is a special type of procedure that does some setup work for the virtual method mechanism. Moreover, the constructor must be called before any virtual method is called. Calling a virtual method without first calling the constructor can block the system, and the compiler has no way to check the order in which the methods are called.

Every object type that has virtual methods must have a constructor.

A warning

The constructor must be called before any other virtual method is called. Calling a virtual method without a previous call to the constructor can cause a system lock and the compiler cannot check the order in which the methods are called.

Note

For object constructors, it is suggested to use the identifier Init.

Each distinct object instance must be initialized with a separate constructor call. It is not enough to initialize one instance of an object and then assign that instance to others. Other instances, even if they may contain valid data, will not be initialized with an assignment operator and will block the system on any calls to their virtual methods. For example:

var

FBee, GBee: Bee; { create two Bee instances }

begin

FBee.Init(5, 9) { constructor call for FBee }

GBee := FBee; { Gbee is invalid! }

end;

What exactly does a constructor create? Each object type contains something called a virtual method table (VMT) in the data segment. The TVM contains the size of the object type and, for each virtual method, a pointer to the code that executes that method. A constructor establishes a relationship between the object's calling implementation and the object's type TCM.

It is important to remember that there is only one TBM for each object type. Separate instances of an object type (i.e., variables of this type) contain only the connection to the TBM, but not the TBM itself. The constructor sets the value of this connection to TBM. It is because of this that nowhere can you start execution before calling the constructor.

5. Object data fields and formal method parameters

The implication of the fact that methods and their objects share a common scope is that a method's formal parameters cannot be identical to any of the object's data fields. This is not some new limitation imposed by object-oriented programming, but rather the same old scope rules that Pascal has always had. This is the same as preventing a procedure's formal parameters from being identical to the procedure's local variables:

procedure CrunchIt(Crunchee: MyDataRec, Crunchby,

ErrorCode: integer);

var

A, B: char;

ErrorCode: integer;

begin

.

.

.

A procedure's local variables and its formal parameters share a common scope and therefore cannot be identical. You will get "Error 4: Duplicate identifier" if you try to compile something like this, the same error occurs when you try to set a formal method parameter to the name of the field of the object to which the method belongs.

The circumstances are somewhat different, as putting the procedure header inside a data structure is a nod to an innovation in Turbo Pascal, but the basic principles of Pascal scope have not changed.

Author: Tsvetkova A.V.

<< Back: Methods (Methods. Constructors and destructors. Destructors. Virtual methods. Object data fields and formal method parameters)

>> Forward: Assembler (About assembler. Microprocessor software model. User registers. General purpose registers. Segment registers. Status and control registers)

We recommend interesting articles Section Lecture notes, cheat sheets:

Methods of teaching psychology. Lecture notes

pathological physiology. Crib

History of culture. Lecture notes

See other articles Section Lecture notes, cheat sheets.

Read and write useful comments on this article.

<< Back

Latest news of science and technology, new electronics:

The existence of an entropy rule for quantum entanglement has been proven 09.05.2024

Quantum mechanics continues to amaze us with its mysterious phenomena and unexpected discoveries. Recently, Bartosz Regula from the RIKEN Center for Quantum Computing and Ludovico Lamy from the University of Amsterdam presented a new discovery that concerns quantum entanglement and its relation to entropy. Quantum entanglement plays an important role in modern quantum information science and technology. However, the complexity of its structure makes understanding and managing it challenging. Regulus and Lamy's discovery shows that quantum entanglement follows an entropy rule similar to that for classical systems. This discovery opens new perspectives in the field of quantum information science and technology, deepening our understanding of quantum entanglement and its connection to thermodynamics. The results of the study indicate the possibility of reversibility of entanglement transformations, which could greatly simplify their use in various quantum technologies. Opening a new rule ... >>

Mini air conditioner Sony Reon Pocket 5 09.05.2024

Summer is a time for relaxation and travel, but often the heat can turn this time into an unbearable torment. Meet a new product from Sony - the Reon Pocket 5 mini-air conditioner, which promises to make summer more comfortable for its users. Sony has introduced a unique device - the Reon Pocket 5 mini-conditioner, which provides body cooling on hot days. With it, users can enjoy coolness anytime, anywhere by simply wearing it around their neck. This mini air conditioner is equipped with automatic adjustment of operating modes, as well as temperature and humidity sensors. Thanks to innovative technologies, Reon Pocket 5 adjusts its operation depending on the user's activity and environmental conditions. Users can easily adjust the temperature using a dedicated mobile app connected via Bluetooth. Additionally, specially designed T-shirts and shorts are available for convenience, to which a mini air conditioner can be attached. The device can oh ... >>

Energy from space for Starship 08.05.2024

Producing solar energy in space is becoming more feasible with the advent of new technologies and the development of space programs. The head of the startup Virtus Solis shared his vision of using SpaceX's Starship to create orbital power plants capable of powering the Earth. Startup Virtus Solis has unveiled an ambitious project to create orbital power plants using SpaceX's Starship. This idea could significantly change the field of solar energy production, making it more accessible and cheaper. The core of the startup's plan is to reduce the cost of launching satellites into space using Starship. This technological breakthrough is expected to make solar energy production in space more competitive with traditional energy sources. Virtual Solis plans to build large photovoltaic panels in orbit, using Starship to deliver the necessary equipment. However, one of the key challenges ... >>

Random news from the Archive

Diamond tool in the stone age 08.05.2005

American physicist Peter Liu, studying the composition of four stone axes found in ancient Chinese burials near Shanghai, found that they are composed mainly of corundum. This is the second hardest (after diamond) natural mineral, meanwhile, the axes, whose age archaeologists estimate at 4500-6000 years, are polished to a mirror shine.

Until now, it was believed that the ancient inhabitants of China used quartz sand for grinding, but quartz is too soft compared to corundum. Taking the same rock, Liu tried to grind it on a modern grinding machine using three common abrasive powders - quartz, corundum and diamond.

It was possible to obtain a surface of such purity as on Stone Age axes only with the help of diamond powder. By the way, two diamond placers are known about 300 kilometers from the place of discovery.

Other interesting news:

▪ SIMO PMIC Converter MAX77654

▪ Photonic chip converting waves with high efficiency

▪ Film that increases the impact resistance of the smartphone display

▪ Aquarium fish for astronauts

▪ Car in ceramic armor

News feed of science and technology, new electronics

 

Interesting materials of the Free Technical Library:

▪ site section Power regulators, thermometers, heat stabilizers. Article selection

▪ article Flea market. Popular expression

▪ article In which country was an MP elected who promised more tailwinds on bike lanes? Detailed answer

▪ article Lake Ladoga. Nature miracle

▪ article Television antennas. Directory

▪ article S-metr for HF radio. Encyclopedia of radio electronics and electrical engineering

Leave your comment on this article:

Name:


Email (optional):


A comment:





All languages ​​of this page

Home page | Library | Articles | Website map | Site Reviews

www.diagram.com.ua

www.diagram.com.ua
2000-2024