Several containers in C Builder
------- Implementation of arrandon in BCB
C Builder is Borland's rapid development tool based on C , and its simple use of methods and power have been well received by many programmers. C Builder (hereinafter referred to as BCB) component library is the same as Delphi, is VCL. Unlike Microsoft's MFC, VCL is fully compiled with Object Pascal language. Therefore, the BCB has also achieved powerful features of PASCAL and C .
This paper introduces a lot of articles that implement the array of controls in the BCB, but implementation methods, mostly using the TLIST class comes with VCL. In fact, in addition to this method, there are still many other methods in the BCB to implement the controls. Here, I will talk about these methods that implement the array of controls, in fact, it is also a summary of the container usually used in BCB.
BCB fully supports VCL and standard C , which results in a container having two versions of VCL versions and standard C . Here, I will give three implementation methods, one is a VCL's TList method, one is a VCL DynamicAy (dynamic array) method, and there is a standard C STL implementation method. I believe these substantially covers several container types that are often used in BCB.
I have designed an example to demonstrate the container I said and how they use it.
First let me introduce my routine. It is very simple but very representative, the following is its interface:
You can see that in this routine, we manage a set of TIMAGE controls (that is, "Mountain" icons there), we can add new "mountains" to our "mountain" (will random In the form of PANEL), we can also delete any "mountains" we don't want. At the same time, I also provided "all clear", all of the "Mountain" can be cleared in the way. The three containers I want to say are in this program as routines, and the only difference on the appearance is that the title of this form varies.
I will talk about the most TLIST class for everyone.
The TLIST class provided by the VCL implements a linear linked table object that can be dynamically stored. It is actually implemented in a storage pointer (chain storage), but it also provides sequential storage. You can access each item of the TList object as an array via the Items property. In addition, the TLIST class provides a convenient and comprehensive linked table function. For example, a full set of deleting a lookup sorted object method and a number of items containing the count attribute access to the list.
The concept is finished, let's take a look at how this TLIST version of "I can see the mountain" is achieved. The form is simple, nothing more than a form, a panel, a Listbox, three button. I will not go into the simple stack of these controls.
TLIST is a container, but it is also a class, so we have to create this class before use. For the sake of simplicity, I define this TLIST class pointer to a private pointer so that all functions in this class can easily access it. So I have the following definition in the private section of the header file:
TLIST * HILLLIST;
Next, we will define three private functions to respond to three different buttons. So my Private paragraph has such something:
Void __fastcall addhill ();
Void __fastcall deletehill ();
Void __fastcall clearll ();
Ok, now we should have the specific implementation of the relationship function. First, I have to create my container, so I executed in the form of the form: hilllist = new tlist ();
HillList describes a pointer to this container. Let's give the original code implemented by the function and explain it.
/ ** Add members ** / ** /
Void __fastcall tfrmHill :: addhill ()
{
TIMAGE * TEMIMAGE; / / Define temporary TIMAGE pointer
Hilllist-> add (new timage (this)); / / Configure the new Image object and add it to the control array.
HillListbox-> items-> add ("a hill"); / / Write "A Hill" to ListBox
TemImage = (TIMAGE *) HillList-> items [(hilllist-> count-1)]; // Get the just-constructed image object
TemImage-> Picture-> LoadFromfile ("hill.ico"); // Load the picture
TemImage-> top = random (hillpanel-> height); // set the location of the new Image as
TemImage-> left = random (hillpanel-> width); // random value in //
TemImage-> parent = hillpanel; // This sentence is essential, used to explain
} // Image is in Panel.
/ / -------------------------------------------------------------------------------------------- -------------------------------------------------- -------------------
/ ** Delete members selected in the control array ** /
Void __fastcall tfrmHill :: deletehill ()
{
IF (HillListbox-> ItemIndex> = 0) // Deconed that there is a selected object in Listbox
{
TIMAGE * TEMIMAGE = (TIMAGE *) HillList-> items [hilllistbox-> itemindex]; // load temporary pointer
Delete TemImage; // Delete the object referred to in the pointer
Hilllist-> delete (hilllistbox-> itemindex); // Delete pointer records in the control array
HillListbox-> items-> delete (hilllistbox-> itemindex); // Remove an object in ListBox
}
}
Note that in the operation of the object above, we first get the pointer to the objects in the control array, then use the Delete operator to destroy the object's destruction function destroyed the object, this step is not possible, this is a possibility of memory disclosure Opportunity. Then, you have to delete a pointer to the object in the control array, so that all the nine people are generally all destroyed with this object.
/ / -------------------------------------------------------------------------------------------- -------------------------------------------------- ------------------- / ** Clear control array ** /
Void __fastcall tfrmhill :: cleArall ()
{
TIMAGE * TEMIMAGE; / / Establish temporary pointer
For (int i = 0; i
Count; i )
//
Cailess control array
{
TemImage = (TIMAGE *) hilllist-> items [i]; // points temporary pointer to the object to be operated
Delete TemImage; // Destroy the object
}
HillList-> CLEAR (); / / Clear control array, at this time, all pokes pointing within the control unit pointing
// has been destroyed, and if you visit these addresses at this time, it will cause a
// AV error
HillListbox-> items-> clear (); // Clear ListBox
}
Deleting all objects, there is also two steps, so I first traverse the array of controls, destroy all objects inside, and then empty the array of controls, so that it really realizes empties.
The main function is over, this time there is a job to do, don't forget, our container class is dynamically applied, so, like other classes, our container needs to be destroyed, so we must Add in the form of the form:
Delete hilllist;
These are the methods of implementing an array of controls with TLIST. It can be seen that this method is simple, and the array is stored in the form of a pointer (TLIST can only be stored in the form of a pointer). Adding and deleting objects is very convenient and efficient. However, TLIST is not a type of secure class, and its pointer is stored in a void type. So we can also see that we have used forced type conversion when you call them. For this reason, it has brought unsafe hidden dangers for our procedures. Also, when it stores 5,000 objects, the efficiency will have a big decline. The TLIST class is a class defined by the VCL, so its portability is very poor.
Below we introduce a type of safe container, which is the dynamicAmicArray provided by the VCL. The dynamic array of VCL is implemented in a class. It provides a DynamicArray class template that uses this class template to declare the actual dynamic array class. The dynamic array can dynamically change the number of array elements when running at runtime by setting the length value. Moreover, it also overloads the "[]" operator of the C-style array, so you can access the dynamic array like accessing a normal array.
Below I show you DynamicArray implementation of "I can see the mountain" today.
With a dynamic array, we must first declare this container. In the private section of the header file:
DynamicArray
Hillda;
Then there are three important functions:
Void __fastcall addhill ();
Void __fastcall deletehill ();
Void __fastcall clearll ();
This has no difference with our first version. Let's take a look at the implementation of the program. There are a lot of operations in the following programs that are the same in the first version, no longer explained.
Because the dynamic array is a template class, we don't need to create its object before use.
/ / -------------------------------------------------------------------------------------------- -------------------------------------------------- ------------------ / ** Add members ** /
Void __fastcall tfrmHill :: addhill ()
{
TIMAGE * TEMIMAGE;
Hillda.length = 1; // Dynamic array length plus one to the new object
Hillda [hillda.high] = (New Timage (this)); // put the new space into a newly created image
// Targe of object
HillListbox-> items-> add ("a hill"); / / Write "A Hill" to ListBox
TemImage = hillda [hillda.high]; // Get the image object of the just constructed
TemImage-> Picture-> LoadFromFile ("Hill.ico");
TemImage-> top = random (hillpanel-> height);
TemImage-> Left = random (hillpanel-> width);
Temimage-> parent = hillpanel;
}
/ / -------------------------------------------------------------------------------------------- ---------------------------
/ ** Delete members selected in the control array ** /
Void __fastcall tfrmHill :: deletehill ()
{
IF (hilllistbox-> itemindex> = 0)
{
Delete hillda [hilllistbox-> itemindex]; // Destroy the selected object
For (int i = hilllistbox-> itemindex; i {// a front shift cover is deleted Hillda [i] = HILLDA [i 1]; // pointer } Hillda.Length- = 1; // Control Array Total Length Reduction HillListbox-> items-> delete (HillListbox-> ItemIndex); } } / / -------------------------------------------------------------------------------------------- -------------------------------------------------- ---------------- / ** Clear control array ** / Void __fastcall tfrmhill :: cleArall () { For (int i = 0; i // The same traversal control array destroys all classes { Delete Hillda [I]; } HillDa.Length = 0; // Set the length of the control array to 0 to release the array of controls HillListbox-> items-> clear (); } / / -------------------------------------------------------------------------------------------- -------------------------------------------------- ------------ DynamicArray method finished, what is the careful readers? If I tell you a fact, you will see it. DynamicArray is stored in a continuous space. It implements the mechanism for the length of the runtime. This is the case: When you change its length while running, it will allocate a memory from the new length, and then all the original data is all Copy goes in the new address. My day ~~~~, so that you know, our DynamicArray control is too big, when we add and delete, it is always talking to Copy, less objects It is still not obvious. When the object has changed a lot, such system overhead is really unacceptable. Well, the first two methods have certain defects, then I will talk about the third method: STL method! Standard Template Library (STL) is part of the C standard library that defines a set of containers and algorithms that operate on the container. These algorithms are very efficient. Borland C Builder 6 has built-in STL's actuator "Stlport 4.5". By using these generic containers and algorithms, our programs can be more robust and efficient. Based on the requirements of the array of controls, I will prepare the VECTOR container in STL. Vector provides an alternative representation for built-in arrays. It also uses continuous memory space to store data. Such a structure has caused the efficiency of its random access but in any position, rather than inserting data at the end of the Vector, the efficiency is very low (this is similar to our DynamicArray, just DynamicArray is inserting data at the end. Low), will the vector will be the same as DynamicArray? Of course, the vector is more efficient than DynamicArray when inserting data at the end, because it uses a self-growth mechanism. That is to say, in order to improve efficiency, actually grow with each element, but when the vector needs to grow itself, it actually allocates more space than the current space, that is, it assigns it. Some additional memory spaces, or it reserved these storage areas (the specific number of additional spaces allocated is defined by specific implementation). Our vector of our storage pointer will expand to 256 when the first element is inserted. When we inserted the element to 256, it will apply for a double-time space, copy the original value to the newly allocated memory space, release the original memory space. Anyway, if you are ready to insert the object inserted into your control (at least 10 million, the efficiency of the Vector is the highest (with other STL containers and other traditional container ratios). However, if you are very demanding for the operation of the elements in the control array, you can use the LIST container in STL. I am not so demanding this requirement, so my program is implemented with a vector. To implement the vector in BCB, don't forget to include its header file: #include "hillstl.h" Then we have to declare our namespace: Using namespace std; Define a Vector in the private section of the header: Vector HillVec; three functions: Void __fastcall addhill (); Void __fastcall deletehill (); Void __fastcall clearll (); / / -------------------------------------------------------------------------------------------- -------------------------------------------------- ---------------- / ** Add members ** / ** / Void __fastcall tfrmHill :: addhill () { TIMAGE * TEMIMAGE; HillVec.push_back (New Timage (this)); // Add new object's pointer to the control array HillListbox-> items-> add ("a hill"); TemImage = * (HillVec.end () - 1); // get a pointer to the object TemImage-> Picture-> LoadFromFile ("Hill.ico"); TemImage-> top = random (hillpanel-> height); TemImage-> Left = random (hillpanel-> width); Temimage-> parent = hillpanel; } / / -------------------------------------------------------------------------------------------- -------------------------------------------------- ---------------- / ** Delete members selected in the control array ** / Void __fastcall tfrmHill :: deletehill () { IF (hilllistbox-> itemindex> = 0) { TIMAGE * TEMIMAGE = * (HillVec.Begin () HillListbox-> ItemIndex); Delete Temimage; HillVec.Rase (HillVec.Begin () HillListbox-> ItemIndex); / / Delete the value specified in the control array HillListbox-> items-> delete (HillListbox-> ItemIndex); } } / / -------------------------------------------------------------------------------------------- -------------------------------------------------- ---------------- / ** Clear control array ** / Void __fastcall tfrmhill :: cleArall () { Vector :: Iterator it; // Definition For (iter = hillvec.begin (); it! = hillvec.end (); it ) // Traverse the destroyable object { delete * it; } HillVec.Rase (HillVec.Begin (), HillVec.end ()); // Empty VECTOR HillListbox-> items-> clear (); } Ok, this is our third approach. This method is preferably the best, and its strong strongness is strong and the portability is strong. However, it is not good to operate in the container. The STL's List is not good when random access. It can be seen that there is no one in the world! Do you know better way? Come tell me. In the above three methods, you can see that in addition to the TLIST can only store the pointers, DynamicArray and Vector are any type of container that can store any type of container. Why don't we store pointers? This is the case, if we store the class, it is actually a copy of the object. At this time, when we perform insertion operation, the object will call its own copy constructor to generate a copy of the object. Such efficiency is reduced, so we store in the form of a pointer, and such design methods also increase the efficiency of program processing. The above I combined with the control array introduced three containers commonly used in BCB. You can consider the actual situation in practical applications to choose the container for yourself. All programs in this article are touched under Windows2000 BCB5. If there is any problem talking about the technology here, welcome to discuss with me, address: Child_bj@163.com Zhang Qi, Beijing Union University Information