Register for EarthWeb's Million Dollar Sweepstakes!
home account info subscribe login search My ITKnowledge FAQ/help site map contact us


 
Brief Full
 Advanced
      Search
 Search Tips
To access the contents, click the chapter and section titles.

C++ in Plain English
(Publisher: IDG Books Worldwide, Inc.)
Author(s): Brian Overland
ISBN: 1558284729
Publication Date: 04/01/96

Bookmark It

Search this book:
 
Previous Table of Contents Next


Who Needs Friends?

All the operator functions discussed so far have been declared with the friend keyword within the CStr class. Normally, functions not declared in a class have access only to the public members. The friend keyword offers a way around this restriction. A function declared as a friend to a given class has access to all members in the class and not just to those that are public. The function may be a global function—that is, not declared within any class—or a function that is a member of a different class.

For example, the function setbk is a friend of the class CBook; this enables it to access private members of the class: a, b, and c.

class CBook {
    int a, b, c;
    friend void setbk(CBook bk, int x, int y, int z);
};

void setbk(CBook bk, int x, int y, int z) {
   bk.a = x;
   bk.b = y;
   bk.c = z;
}

The purpose of friend functions is to make possible functions such as operator+(char*, CStr). You can implement operator functions as member functions, but such functions assume that an object of the class appears on the left side of the operator. Along this line, the function operator+(CStr, char*) could have been written this way:

class CStr {
...
    CStr operator+(char *s);
}

CStr CStr::operator+(char *s) {
    CStr new_string(*this);
    new_string.cat(s);
    return new_string;
}

The first statement in the body of the definition initializes the new string with an object referred to as *this. The value of *this is none other than the left operand. To understand how the code works, remember that this approach to defining addition translates an expression as shown in Figure 7.3.


Figure 7.3  Translation of operation into a member function call.

With this approach, addition is translated into a member function called through the left operand, which is a CStr object. In C++, the this keyword is a pointer to the current object, and *this refers to the object itself. So the first statement initializes new_string to the contents of the left operand by referring to *this.

    CStr new_string(*this);

I’ll have more to say about the this keyword later in this chapter and in Part III.

In any case, the problem with writing operator functions this way is that it restricts you to always having your class object on the left side of the operator. Only with nonmember functions is it possible to write a function that tells how to evaluate

s + string

reversing the operands shown earlier. For this reason, binary operators are usually implemented as friend functions and not member functions. (Binary operators should be friends so that the function can access private data if needed.) That’s the approach I adopted at the beginning of the chapter:

class CStr {
...

    CStr friend operator+(CStr str1, CStr str2);
    CStr friend operator+(CStr str, char *s);
    CStr friend operator+(char *s, CStr str);
};

An exception to the use of friends is the assignment operator, which must be implemented as a member function and not a friend—as you’ll see in the next section.

Writing the Assignment Function

Assignment (=) is another one of those operations for which the compiler supplies a default, hidden function. As a general rule, assignment between objects of the same type is always supported in C++, just as direct assignment between structures is supported in standard C. Therefore, statements such as the following are valid:

CStr string1, string2;
...
string1 = string2;    // Assign value of string2 to
                      // string1
It’s possible to avoid assignment altogether if you want to: define an assignment operator function and then make it private to the class.

However, as with copy construction, the compiler-supplied assignment behavior is inadequate for a class such as CStr, which uses dynamic-memory allocation. This default behavior is a simple member-by-member copying. As pointed out in Chapter 6, this behavior can lead to major errors.

Therefore, when you write a class such as CStr, defining the behavior of the assignment operator is important. The assignment operator function must be a member of the class, with the following prototype within the class declaration:

    class& operator=(const class &arg);

The argument name is optional. The corresponding function definition has the following syntax:

class& class::operator=(const class &arg) {
    statements
}

In the CStr class, the assignment operator function could have the following prototype. The only aspect of this declaration that you have a choice about is the argument name.

class CStr {
...
   CStr& operator=(const CStr &source);
};

The assignment operator declaration can be intimidating to C++ beginners, because so much of it uses syntax elements not found in C. All the syntax elements have been introduced in this and previous chapters. But it may help a to review them. Figure 7.4 analyzes the syntax of the CStr-to-CStr assignment function.


Figure 7.4  Analysis of assignment operator declaration.

The Assignment Function Definition

The assignment function turns out to be trivial to write once you understand all the syntax. Here’s the shortest version of this function:

CStr& CStr::operator=(const CStr &source) {
    cpy(source.get());
    return *this;
}

The function doesn’t need to be any longer than this; it works perfectly well in fact, this function is so short that it is a good candidate for function inlining. The definition can be given in the CStr declaration.

class CStr {
...
    CStr& operator=(const CStr &source)
         {cpy(source.get()); return *this; }
};


Previous Table of Contents Next
[an error occurred while processing this directive]

Products |  Contact Us |  About Us |  Privacy  |  Ad Info  |  Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.