hjk41的日志

Avatar

Effective C++ Note 19: member functions, non-member functions and friend functions

main points:
1. Virtual functions must be member functions.
2. Operator >> and << are never member functions.
3. Only non-member functions get type conversions on their left-most argument.
4. Everything else should be a member functions.

Point No. 1 is without debate, so we'll just past it by.
Operator >> and << are never member functions
When we use operator >> and <<, we use it this way:

cin>>C;
cout<<C;


where C is an instance of some class. So if we decide to write operator >> and << for our class, the right thing to do is to define them as non-member functions. If you define them as member functions, your will have to put C on the left, as shown below:

class String {
public:
  String(const char *value);
  ...
  istream& operator>>(istream& input);
  ostream& operator<<(ostream& output);
private:
  char *data;
};
String C;
C>> cin;                   // legal, but contrary
                            // to convention
C<< cout;                  // ditto


That would confuse everyone. So here comes the right one:

istream& operator>>(istream& input, String& string)
{
  delete [] string.data;
 [i] read from input into some memory, and make string.data
  point to it[/i]  
  return input;
}
ostream& operator<<(ostream& output,
                    const String& string)
{
  return output << string.data;
}

Only non-member functions get type conversions on their left-most argument
Consider overloading operator + for String like this:

const String String::operator + (const String & rhs){...};
String a="Hello";
char * b="world";
a=a+b;  // fine
a=b+a;  // error!


Why does the first one works while the other doesn't? Because when we do a=a+b, its treated like this:

String temp(b); // implicit conversion
a=a+temp;


The implicit conversion is possible because we have a constructor that takes const char * as the argument. However, implicit type conversion will never happen to the object on which a member function is invoked. So the only way to make a=b+a work is to write operator + as non-member function like this:

const String operator + (const String & a, const String & b){...};


评论已关闭