Файл: Interfacing with C plus plus-programing communication with microcontrolers (K. Bentley, 2006).pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 14.06.2025

Просмотров: 3564

Скачиваний: 1

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

12 DATA ACQUISITION WITH OPERATOR OVERLOADING 373

There is a lesson to be learned from this exercise - whenever class objects are passed to a function it is prudent to pass them by reference. As shown in Listing 12-2, the keyword const can be prefixed to the parameter passed by reference to protect the parameter from any inadvertent changes within the function.

12.2.4 The Copy Constructor

In previous chapters we used default constructors and standard constructors to instantiate objects. The copy constructor is a special constructor that is called when a copy of an object is created. If the developer does not provide a copy constructor, the compiler will generate one by default. This constructor makes a copy of an object by copying member-by-member from one object to the other for three situations:

(i)When passing parameters to a function by value, a copy of the object must be created.

(ii)When parameters are returned by value, a copy of the object to be returned must be made. Again, the same copy constructor will be called to make the copy.

(iii)If an object is declared and initialised using another object passed as a parameter, the copy constructor must be called.

The assignment operator can also be used to initialise an object that was created previously using the default constructor. In principle, the assignment operator (=) must carry out the same actions as the copy constructor. If the developer does not overload the assignment operator the compiler will do so to suit the class. We will defer discussing overloading the assignment operator until operator overloading concepts have been described.

A few examples of object instantiation using various constructors are:

DCMotor Motor1;

// default

constructor used

DCMotor Motor2(Motor1);

// copy constructor used

DCMotor Motor3;

//

default

constructor

used

Motor3 = Motor1;

//

assignment operator

used

We will develop an example program that operates with arrays using the IntArray object to improve your understanding of the copy constructor. Consider the definition of the IntArray class given in Listing 12-3.

Listing 12-3 Header file intarray.h shows a class definition for an array of integers.

#ifndef IntarrayH #define IntarrayH

class IntArray

{

private:


374 12 DATA ACQUISITION WITH OPERATOR OVERLOADING

int NumInts;

int* ArrayPointer;

public:

// Default constructor

IntArray();

IntArray(int numints);

// Constructor

~IntArray();

// Destructor

void EnterArray();

// Other member functions

void PrintArray();

};

#endif

The IntArray class will instantiate an array of integers having a specified number of elements. The data member NumInts will store the total number of elements in the array and the pointer ArrayPointer will point to the dynamically allocated portion of memory containing the array of integers. The destructor ~IntArray() will release the dynamically allocated memory. The function EnterArray() will prompt the user for array values, receive user input via the keyboard, and fill the array. The final function PrintArray() is used to print the contents of the array on the screen.

The IntArray class’s constructor and its default constructor initialise the member data NumInts and ArrayPointer. If a parameter is passed to the constructor, memory for the array will be dynamically allocated as shown in the following constructor definitions:

IntArray::IntArray() // Default constructor

{

NumInts = 0; ArrayPointer = NULL;

}

IntArray::IntArray(int numints)

// Constructor

{

if(numints <=0)

{

NumInts = 0;

ArrayPointer = NULL;

}

else

{

NumInts = numints;

ArrayPointer = new int[NumInts];

}

}


12 DATA ACQUISITION WITH OPERATOR OVERLOADING 375

Note that if the value of numints is 0 or negative, NumInts is initialised to 0 and ArrayPointer is initialised to the predefined constant NULL to indicate that the pointer is not pointing anywhere.

Suppose we use the object class IntArray in a main() function to instantiate two IntArray objects named A and B. We will then pass the objects A and B by value to a function named AddArrays() to add the IntArray object A to the IntArray object B as shown in the fragment of code below:

void AddArrays(IntArray a, IntArray b) // Pass by value

{

// print the result of summation on-screen

}

void main()

{

IntArray A(5); IntArray B(5);

AddArrays(A,B);

.

.

.

}

Object A

Object B

NumInts

NumInts

ArrayPointer

ArrayPointer

Copy of A

Copy of B

NumInts

NumInts

ArrayPointer

ArrayPointer

Memory dynamically allocated by the constructors

Figure 12-1 Objects A and B copied by the compiler-generated copy constructor.

When the actual arguments A and B are passed by value to the function AddArrays(), copies of A and B must be made. The compiler-generated copy


376 12 DATA ACQUISITION WITH OPERATOR OVERLOADING

constructor will be called to make these copies; this copy-making process is shown graphically in Figure 12-1.

The compiler-generated copy constructor has created a copy of each data member of the original objects. However, it did not make copies of the dynamically allocated memory. As a result, the pointer to the original object and the pointer to the copied object point to the same portion of memory.

The destructor ~IntArray() is called after the function AddArrays() executes. The destructor will free the memory used for the temporary copies of A and B together with the original data objects that were dynamically allocated. This outcome is shown in Figure 12-2.

Object A

Object B

NumInts

NumInts

ArrayPointer

?

ArrayPointer

?

Figure 12-2 Result of discarding the copies of A and B.

Object A

Object B

NumInts

NumInts

ArrayPointer

ArrayPointer

Memory dynamically allocated

Copy of A

by the constructors

Copy of B

NumInts

NumInts

ArrayPointer

ArrayPointer

Memory dynamically allocated

by the copy constructors

Figure 12-3 Copies of objects A and B made by a user written copy constructor.

Now the main() function has lost the original data it had created at the time of instantiating the objects A and B. We can overcome the problem created by the compiler-generated copy constructor if we write our own copy constructor that not