Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
C++ For Dummies (2004) [eng].pdf
Скачиваний:
84
Добавлен:
16.08.2013
Размер:
8.09 Mб
Скачать

Chapter 14: Point and Stare at Objects 191

Calling a function by using the reference operator

The reference operator described in Chapter 9 works for user-defined objects. The following PassObjRef demonstrates references to user-defined objects:

//PassObjRef - change the contents of an object in

//a function by using a reference #include <cstdio>

#include <cstdlib> #include <iostream> using namespace std;

class Student

{

public:

int semesterHours; float gpa;

};

// same as before, but this time using references void someFn(Student& refS)

{

refS.semesterHours = 10; refS.gpa = 3.0;

cout << “The value of refS.gpa = “ << refS.gpa << “\n”;

}

int main(int nNumberofArgs, char* pszArgs[])

{

Student s; s.gpa = 0.0;

//display the value of s.gpa before calling someFn() cout << “The value of s.gpa = “ << s.gpa << “\n”;

//pass the address of the existing object

cout << “Calling someFn(Student*)\n”; someFn(s);

cout << “Returned from someFn(Student&)\n”;

// the value of s.gpa is now 3.0

cout << “The value of s.gpa = “ << s.gpa << “\n”;

//wait until user is ready before terminating program

//to allow the user to see the program results

192 Part III: Introduction to Classes

system(“PAUSE”); return 0;

}

In this example, C++ passes a reference to s rather than a copy. Changes made in someFn() are retained in main().

Passing by reference is just another way of passing the address of the object. C++ keeps track of the address of a reference, whereas you manipulate the address in a pointer.

Why Bother with Either

Pointers or References?

Okay, so both pointers and references provide relative advantages, but why bother with either one? Why not just always pass the object?

I discussed one obvious answer earlier in this chapter: You can’t modify the object from a function that gets nothing but a copy of the structure object.

Here’s a second reason: Some objects are large — I mean really large. Passing such an object by value means copying the entire thing into the function’s memory.

The area used to pass arguments to a function is called the call stack.

The object will need to be copied again should that function call another, and so on. After a while, you can end up with dozens of copies of this object. That consumes memory, and copying all the objects can make execution of your program slower than booting up Windows.

The problem of copying objects actually gets worse. You see in Chapter 18 that making a copy of an object can be even more painful than simply copy­ ing some memory around.

Returning to the Heap

The problems that exist for simple types of pointers plague class object pointers as well. In particular, you must make sure that the pointer you’re using actually points to a valid object. For example, don’t return a reference to an object defined local to the function:

Chapter 14: Point and Stare at Objects 193

MyClass* myFunc()

{

// the following does not work MyClass mc;

MyClass* pMC = &mc; return pMC;

}

Upon return from myFunc(), the mc object goes out of scope. The pointer returned by myFunc() is not valid in the calling function.

The problem of returning memory that’s about to go out of scope is dis­ cussed in Chapter 9.

Allocating the object off the heap solves the problem:

MyClass* myFunc()

{

MyClass* pMC = new MyClass; return pMC;

}

The heap is used to allocate objects in a number of different situations.

Comparing Pointers to References

I hate to keep referencing pointers and pointing to references, but new pro­ grammers often wonder why both are needed.

Actually, you could argue that you don’t need both. C# and most other lan­ guages don’t use pointers. However, pointer variables are an ingrained part of good ol’ standard non-Visual Studio.NET–specific C++.

Why Not Use References

Rather Than Pointers?

The syntax for manipulating a reference is similar to that used with normal objects. So why not just stick with references and never look back at pointers?

Objects and their addresses aren’t the same thing. Many times, the syntax for a reference actually becomes more complicated than that for pointers. Consider the following examples:

194 Part III: Introduction to Classes

class Student

{

public:

int semesterHours; float gpa;

Student valFriend; Student& refFriend; Student* ptrFriend;

};

int main(int nNumberofArgs, char* pszArgs[])

{

//the following declares a reference off of the heap

//(simple enough)

Student& student = *new Student; student.gpa = 10;

// ditto

Student& studentFriend = *new Student; studentFriend.gpa = 20;

//the following copies the value of one Student

//object into the second

student.valFriend = studentFriend;

//this doesn’t work at all Student& refFriend; refFriend = studentFriend;

//this does work student.pFriend = &studentFriend;

return 0;

}

As you can see, I modified that Student class so that one Student can refer­ ence her best buddy. I tried to use the reference variable type to do so. I cre­ ated two students in main() in an attempt to link the one student object to its studentFriend.

The first assignment in the body of the program copies the contents of the friend into the data member — Student object contains a body double. The second assignment doesn’t work at all — C++ can’t differentiate assigning an object to a reference variable from assignment to an object itself. Only the third assignment works. The student object points to the address of the studentFriend, which is exactly what you want.