1. Trang chủ
  2. » Công Nghệ Thông Tin

A Complete Guide to Programming in C++ part 49 potx

10 316 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 198,21 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

If the array elements are of a class type, the class must have a default constructor, since you cannot supply an initialization list when calling new[].. To do so, a newer bigger array i

Trang 1

The operators newanddeletewere designed to create and destroy instances of a class dynamically In this case, in addition to allocating memory, a suitable constructor must

be called Before releasing memory, the destructor must be called to perform cleaning up tasks However, the operators newanddeleteensure that this happens

䊐 Calling new with a Default Constructor

A call to newfor a class is not much different from a call for a fundamental type Unless explicitly initialized, the default constructor is called for each new object, but you must make sure that a default constructor exists!

Example: Euro* pEuro = new Euro;

This statement allocates memory for an object of the Euroclass If enough memory is available, the default constructor for Eurois executed and the address of a new object returned

䊐 Explicit Initialization

To initialize an object explicitly, you can state its initial values in parentheses when you callnew

Syntax: Type *ptr = new Type(initializing_list);

The values in the initialization list are passed as arguments to the constructor If the compiler is unable to locate a suitable constructor, an error message occurs

Example: Euro *pE = new Euro( -123,77);

This statement assigns the address of a new Euro class object to the pointer pE The object is initialized using the supplied values The expression *pEthus represents the entire object

Example: *pE += 200; // To add 200 euros

Thepublicmembers are referred to via the member access operator ->

Example: cout << pE->getCents() << endl; // 33

䊐 Releasing Memory

When an object that was created dynamically is destroyed, the deleteoperator makes sure that the object is cleaned up The destructor is first called, and only then is the memory space released

As previously discussed in the section on fundamental types, when you call delete

you must ensure that the pointer is addressing a dynamic object or that you are dealing with a NULL pointer

Trang 2

460 C H A P T E R 2 1 D Y N A M I C M E M O R Y A L L O C A T I O N

// DynArr.cpp // Operators new[] and delete[] for dynamic arrays //

-#include <iostream>

#include <iomanip>

using namespace std;

int main() {

cout << "Using a dynamic array.\n" << endl;

int size = 0, cnt = 0, step = 10, i;

float x, *pArr = NULL; cout << "Enter some numbers!\n"

"End with q or another character " << endl; while( cin >> x)

{ if( cnt >= size) // Array too small? { // => enlarge it

float *p = new float[size+step];

// Copy the numbers: for( i = 0; i < size; ++i)

p[i] = pArr[i];

delete [] pArr; // Release old array: pArr = p; size += step;

} pArr[cnt++] = x;

} // Work with the numbers:

if( cnt == 0) cout << "No invalid input!" << endl;

else { float sum = 0.0;

cout << "Your input: " << endl;

for( i = 0; i < cnt; i++) // To output and { // add

cout << setw(10) << pArr[i];

sum += pArr[i];

} cout << "\nThe average: " << sum/cnt << endl; }

delete [] pArr; // To free the storage return 0;

}

DYNAMIC STORAGE ALLOCATION FOR ARRAYS

Sample program

Trang 3

Imagine you are compiling a program that will store an unknown quantity of elements in

an array Your best option is to let the program create the array dynamically An array of

this type is known as a dynamic array.

Thenew[ ]operator is available for creating dynamic arrays When you call the opera-tor, you must supply the type and quantity of the array elements

Syntax: vekPtr = new Type[cnt];

The pointer vekPtr will then reference the first of a total of cnt array elements

vekPtrhas to be a pointer to Typefor this reason Of course, Typecan also be a class

Example: Account *pk = new Account[256];

This statement allocates memory for 256 Accounttype objects and uses the default con-structor to initialize them Those objects are

pk[0], pk[1], , pk[255],

or in pointer notation:

*pk, *(pk + 1), , *(pk + 255)

If the array elements are of a class type, the class must have a default constructor, since you

cannot supply an initialization list when calling new[] Starting values for the array ele-ments cannot be assigned until later

It is always a good idea to release the memory space occupied by a dynamic array, if the array is no longer needed To do so, simply call the delete[]operator The braces []

tell the compiler to release the whole array, and not just a single array element

Example: delete[] pk;

The operand for delete[]—the pointer pkin this case—must reference the place in

memory that was allocated by a call to new[]! The destructor belonging to the current class is called for each array element This shows the big difference to delete, which would merely call the destructor for *pk, i.e for the first array element

The program on the opposite page stores numbers in a dynamic array The size of the array is adjusted as required To do so, a newer bigger array is created, the data is copied

to the new array, and the memory occupied by the old array is released

Trang 4

462 C H A P T E R 2 1 D Y N A M I C M E M O R Y A L L O C A T I O N

1st element 2nd element 3rd element

first

New last element

last

1st element 2nd element 3rd element

Info

Info

APPLICATION: LINKED LISTS

A simple linked list

Appending a list element

Deleting a list element

first

Removed element

New first element

New second element

Trang 5

䊐 Dynamic Data Structures

Now, let’s implement a linked list as a sample application A linked list is a dynamic data structure that allows easy insertion and deletion of data A data structure defines how data

can be organized in units, stored, and manipulated—as arrays, lists, or trees, for example The type of data structure you choose has a far-reaching effect on the amount of memory you need, the speed of access to the data involved, and the complexity (or sim-plicity) of the algorithms (data operations) you need

In contract to a static data structure, whose size is known before a program is launched, a dynamic data structure can change size while a program is running One

example of this is an array whose size can be changed during runtime

䊐 Defining a Linked List

Another example is a linked list that is stored in main memory and has the following characteristics:

■ each list element contains a data store for the live data and a pointer to the next element in the list

■ each list element—except the first and last elements—has exactly one predeces-sor and one succespredeces-sor The first element in the list has no predecespredeces-sor and the last element no successor

Some elementary operations are defined for linked lists, such as inserting and deleting list

elements, or searching for and retrieving the information stored in a list element

䊐 Advantages

The storage used for the list elements need not be contiguous The main advantage of linked lists is:

■ memory for the list elements is only allocated when needed

■ you only need to move a pointer when inserting or deleting list elements

When an array element is inserted or deleted, the other array elements have to be moved

to make room or fill up the “gap” in the array If there is no room left, you need to allo-cate memory for a new array and copy the data to it before inserting a new element

Trang 6

464 C H A P T E R 2 1 D Y N A M I C M E M O R Y A L L O C A T I O N

// List.h // Defines the classes ListEl and List

//

-#ifndef _LISTE_H_

#define _LISTE_H_

#include "Date.h" // Class Date from Chapter 14

#include <iostream>

#include <iomanip>

using namespace std;

class ListEl // A list element

{ private:

Date date; // Date double amount; // Amount of money

ListEl* next; // Pointer to successor

public:

ListEl( Date d = Date(1,1,1), double b = 0.0,

ListEl* p = NULL) : date(d), amount(b), next(p) {}

// Access methods:

// getDate(), setDate(), getAmount(), setAmount()

ListEl* getNext() const { return next; }

friend class List; };

// -// Defining the class List

class List

{ private:

ListEl* first, *last;

public:

List(){ first = last = NULL; } // Constructor

// Access to the first and last elements:

ListEl* front() const { return first; }

ListEl* back() const { return last; } // Append a new element at the end of the list:

void pushBack(const Date& d, double b);

// Delete an element at the beginning of the list

void popFront();

};

#endif // _LIST_H_

REPRESENTING A LINKED LIST

Classes of header file List.h

Trang 7

䊐 Representing List Elements

You can use a recursive data structure to represent a linked list A recursive data structure

is a data structure containing a pointer to a data structure of the same type Of course, the data structure cannot contain itself—that would be impossible—but it does contain a pointer to itself

Now let’s look at a linked list used to represent transactions in a bank account A transaction is characterized by a date, a sum of money, and the reason for the tion Thus, the list element needed to represent a transaction will contain the transac-tion data in its data store and a pointer to the next element in the list

The class shown on the opposite page, ListEl, was designed to represent list ele-ments To keep things simple, the data store contains only the date and a sum of money The public declaration includes a constructor and access methods for the live data Later, we will be overloading the <<operator in order to output the list

It is common practice to let the pointer for the last element in the list point to NULL This also provides a termination criterion—the nextpointer just needs to be queried for

NULL

䊐 Representing a List

To identify a linked list, you just point a pointer at the first element in the list You can then use the pointer to the successor of each element to address any element in the list

A pointer to the last element in the list is useful for appending new elements

The opposite page shows the class definition for the Listclass The private section comprises two pointers, which reference the first and last list elements respectively The

constructor has an easy job—it simply points both pointers to NULL, thus creating an

empty list The destructor has a more complex task: it has to release the memory occupied

by the remaining list elements

ThepushBack()method is used to append a new element to the end of the list To

do so, memory is allocated dynamically and the new element becomes the successor of what was previously the last element and the lastpointer is updated In addition, the method must deal with a special case, where the list is empty

ThepopFront()method deletes the first element in the list This involves turning the pointer to the first element around to the second element and releasing the memory occupied by the first element The special case with an empty list also applies

Trang 8

466 C H A P T E R 2 1 D Y N A M I C M E M O R Y A L L O C A T I O N

EXERCISES

Notes on exercise 1

Effects of the splice() function

Insert Position

Result

1 st Array

2 nd Array

7 3 5 9 6 2

9 1 4 2 6 8 3 5

7 3 9 1 4 2 6 8 3 5 5 9 6 2

Trang 9

Exercise 1

Write a global function called splice()that “splices” two intarrays together

by first allocating memory for a dynamic array with enough room for both int arrays, and then copying the elements from both arrays to the new array, as follows:

■ first, the elements of the first array are inserted up to a given position,

■ then the second array is inserted,

■ then the remainder of the first array is appended

Arguments: The two intarrays, their length, and the position at which

they are to be spliced

Return value: A pointer to the new array

Exercise 2

Write a global function called merge()that merges two sorted intarrays by first allocating memory for a dynamic array with enough room for both int arrays and then inserting the elements of both arrays into the new array in sequence

Arguments: The two intarrays and their length

Return value: A pointer to the new array

To test the function, modify the program used to sort arrays in Exercise 4 of Chapter 17

Exercise 3

Complete and test the implementation of a linked list found in this chapter

■ First define the access methods shown opposite.Then overload the << operator for the class ListElto allow formatted output of the data in the list elements.You can use the asString()in the date class to do so

■ Then implement the destructor for the Listclass.The destructor will release the memory used by all the remaining elements Make sure that you read the pointer to the successor of each element before destroying it!

■ Implement the methods pushBack()andpopFront() used for append-ing and deletappend-ing list elements

■ Overload the operator <<in the Listclass to output all the data stored

in the list

■ Test the Listclass by inserting and deleting several list elements and repeatedly outputting the list

Trang 10

468 C H A P T E R 2 1 D Y N A M I C M E M O R Y A L L O C A T I O N

SOLUTIONS

Exercise 1

// -// Splice.cpp

// Implements the splice algorithm

//

-#include <iostream>

#include <iomanip>

#include <cstdlib> // For srand() and rand()

#include <ctime> // and for time()

using namespace std;

// Prototype:

int *splice( int v1[], int len1,

int v2[], int len2, int pos);

int main() {

cout << "\n * * * Testing the splice function * * *\n"

<< endl;

int i, len1 = 10, len2 = 5;

int *a1 = new int[len1],

*a2 = new int[len2];

// Initialize the random number generator // with the current time:

srand( (unsigned)time(NULL));

for( i=0; i < len1; ++i) // Initialize the arrays: a1[i] = rand(); // with positive and for( i=0; i < len2; ++i)

a2[i] = -rand(); // negative numbers

// To output the array:

cout << "1 array: " << endl;

for( i = 0; i < len1; ++i) cout << setw(12) << a1[i];

cout << endl;

cout << "2 array: " << endl;

for( i = 0; i < len2; ++i) cout << setw(12) << a2[i];

cout << endl;

cout << "\n At what position do you want to insert "

"\n the 2nd array into 1st array?"

"\n Possible positions: 0, 1, , " << len1

<< " : ";

int pos; cin >> pos;

Ngày đăng: 06/07/2014, 17:21

TỪ KHÓA LIÊN QUAN