C++
  Home arrow C++ arrow Page 3 - C++ Tricks of the Trade: Friend Functions
Dev Articles Forums 
ADO.NET  
Apache  
ASP  
ASP.NET  
C#  
C++  
ColdFusion  
COM/COM+  
Delphi-Kylix  
Design Usability  
Development Cycles  
DHTML  
Embedded Tools  
Flash  
Graphic Design  
HTML  
IIS  
Interviews  
Java  
JavaScript  
MySQL  
Oracle  
Photoshop  
PHP  
Reviews  
Ruby-on-Rails  
SQL  
SQL Server  
Style Sheets  
VB.Net  
Visual Basic  
Web Authoring  
Web Services  
Web Standards  
XML  
Dedicated Servers  
Moblin 
JMSL Numerical Library 
IBM® developerWorks 
Sun Developer Network 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
C++

C++ Tricks of the Trade: Friend Functions
By: Kais Dukes
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 4 stars4 stars4 stars4 stars4 stars / 65
    2002-06-21

    Table of Contents:
  • C++ Tricks of the Trade: Friend Functions
  • Friendly Friends
  • Commutative Operators
  • Friend Classes
  • Conclusion

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT


    C++ Tricks of the Trade: Friend Functions - Commutative Operators


    (Page 3 of 5 )

    Overloading operator+ allows the rational class to behave more like an intrinsic data type. To add two rational numbers, we can overload the operator as a class member:

    const CRational CRational::operator+(const CRational &r)
    {
    // add *this to r, and return the result by value.
    // ...
    }


    The operator+ function can also be overloaded to handle the addition of a rational, and a non-rational type. If n is an integer, and r is a rational then we could implement r + n as a class member:

    const CRational CRational::operator+(const int n)
    {
    // add *this to n, and return the result by value
    // ...
    }


    Since operator+ is an example of a commutative operator, we would expect r + n to have the same semantics as n + r. In the second case we need to use a non-member function:

    class CRational
    {
    friend const CRational
    operator+(const int n, const CRational &r);

    // ...
    }


    This function could be written as a non-friend function, provided that get/set member functions are used. Doing so would turn the function into a plain non-member function, and so it would not be clear how it interacts with the class. By using a friend function, readers of the class declaration see that operator+ forms part of the CRational interface, and is semantically part of the class.

    Friends and Virtual Functions
    A problem with friends is that class member functions can be virtual while non-member functions can’t. The equivalent of a virtual friend function is useful when deriving from a class that has a friend function.

    An example of where the equivalent of a virtual friend would be useful is if serializing an entire class hierarchy. The trick in doing this is to turn the friend function into a lightweight inline proxy function, which forwards the request back to the class. For example, consider the simple base class:

    class CPerson
    {
    friend ostream &operator<< (ostream &out, CPerson &person);

    // ...

    protected:
    virtual ostream &display(ostream &out);

    // ...

    };


    The friend function forwards the display request back to the CPerson class. Note that we pass an instance of CPerson by reference:

    inline ostream &operator<< (ostream &out, CPerson &person)
    {
    return person.display(out);
    }


    In a class hierarchy using the base CPerson class, each derived class has its own implementation of the display function:

    class CBob : public CPerson
    {
    protected:
    virtual ostream &display(ostream &out)
    {
    out << "Bob";
    return out;
    }
    };


    This is just as efficient as using a virtual friend function (if such a thing existed) since a good compiler will replace a call to operator<< with a call to the display function, which each derived class implements.

    More C++ Articles
    More By Kais Dukes


       · A better approach imho is:classB;class A{ A(const & A); A &...
     

    C++ ARTICLES

    - Multiplying Large Numbers with Karatsuba`s A...
    - Large Numbers
    - Dijkstra`s Shunting Algorithm with STL and C...
    - Brief Introduction to the STL Containers
    - The Standard Template Library
    - Templates in C++
    - C++ Programmer Alerts
    - C++ Programming Tips
    - First Steps in (C) Programming, conclusion
    - First Steps in (C) Programming, continued
    - First Steps in (C) Programming, introduction
    - C++ Preprocessor: Always Assert Your Code Is...
    - C++ Preprocessor: The Code in the Middle
    - Programming in C
    - Temporary Variables: Runtime rvalue Detection







    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 6 hosted by Hostway