.NODE

Writing an Operator That Isnt a Member Function

Writing an Operator That Isn t a Member Function

Problem

You have to write a binary operator, and you can't or don't want to make it a class member function.

Solution

Use the operator keyword, a temporary variable, and a copy constructor to do most of the work, and return the temporary object. Example 15-5 presents a simple string concatenation operator for a custom String class.

Example 15-5. Concatenation with a nonmember operator

#include 
#include 

class String { // Assume the String class declaration
 // has at least everything shown here
public:
 String( );
 String(const char* p);
 String(const String& orig);
 ~String( ) {delete buf_;}

 String& append(const String& s);
 size_t length( ) const;
 const char* data( ) const;
 String& operator=(const String& orig);

 // ...
};

String operator+(const String& lhs, const String& rhs) {

 String tmp(lhs); // Copy construct a temp object
 tmp.append(rhs); // Use a member function to do the real work

 return(tmp); // Return the temporary
}

int main( ) {

 String s1("banana ");
 String s2("rancher");
 String s3, s4, s5, s6;

 s3 = s1 + s2; // Works fine, no surprises
 s4 = s1 + "rama"; // Constructs "rama" automatically using
 // the constructor String(const char*)
 s5 = "ham " + s2; // Hey cool, it even does it backward
 s6 = s1 + "rama " + s2;

 std::cout << "s3 = " << s3.data( ) << '
';
 std::cout << "s4 = " << s4.data( ) << '
';
 std::cout << "s5 = " << s5.data( ) << '
';
 std::cout << "s6 = " << s6.data( ) << '
';
}

 

Discussion

A standalone operator is declared and defined similarly to a member function operator. In Example 15-5, I could have implemented operator+ as a member function by declaring it like this:

String operator+(const String& rhs);

In most cases, this will work the same way regardless of whether you define operator+ as a member or nonmember function, but there are at least a couple of reasons why you would want to implement it as a nonmember function. The first is conceptual: does it make sense to have an operator that returns a new, distinct object? operator+ as a member function is not an inspector of the object's state, nor does it alter the object's state. It's a general utility function that happens to operate on Strings, and, therefore, should not be a member function.

The second reason is technical. You can't do the following with a member operator (from the example):

s5 = "ham " + s2;

This won't work because a character string doesn't have an operator+ that takes a String parameter. If, on the other hand, you have defined your standalone operator+ that takes two String parameters, your compiler will look to see if the String class has a constructor that takes a const char* argument (or whatever type you are using with a String) and construct a temporary object at runtime. The above code, therefore, is equivalent to this:

s5 = String("ham ") + s2;

The compiler saves you the extra keystrokes by just looking it up and invoking the constructor for you.

Overloading the left- and right-shift operators (<< and >>) for streams also requires that you use nonmember operators. For example, to put your new object to a stream using left-shift, you would have to declare operator<<, like this:

ostream& operator<<(ostream& str, const MyClass& obj);

Of course, you can subclass one of the standard library stream classes, and add all the left-shift operators you want, but is that really a good idea? If you do that, only code that uses your new stream class will be able to write your custom class's objects to it. If you use a standalone operator, any code in the same namespace can just write your object to an ostream (or read it from an istream) with no problem.

Building C++ Applications

Code Organization

Numbers

Strings and Text

Dates and Times

Managing Data with Containers

Algorithms

Classes

Exceptions and Safety

Streams and Files

Science and Mathematics

Multithreading

Internationalization

XML

Miscellaneous

Index

show all menu





C++ Cookbook
Secure Programming Cookbook for C and C++: Recipes for Cryptography, Authentication, Input Validation & More
ISBN: 0596003943
EAN: 2147483647
Year: 2006
Pages: 241
Similar book on Amazon

Flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net