C ++ operator overloading post

Following is the abstraction of the string class.

class string {
public:
    string(int n = 0) : buf(new char[n + 1]) { buf[0] = '\0'; }
    string(const char *);
    string(const string &);
    ~string() { delete [] buf; }

    char *getBuf() const;
    void setBuf(const char *);
    string & operator=(const string &);
    string operator+(const string &);
    string operator+(const char *);

    private:
       char *buf;
    };

    string operator+(const char *, const string &);
    std::ostream& operator<<(std::ostream&, const string&);

      

I want to know why these two operators overload functions

  string operator+(const char *, const string &);
  std::ostream& operator<<(std::ostream&, const string&);

      

are not class member functions or friend functions? I know that overloaded functions with two parameters are usually friends functions (I'm not sure, I would appreciate if you could enlighten this too), however my professor did not declare them as a friend. Below are the definitions of these functions.

 string operator+(const char* s, const string& rhs) {

           string temp(s);
           temp = temp + rhs;
           return temp;
 }

 std::ostream& operator<<(std::ostream& out, const string& s) {
     return out << s.getBuf();
 }

      

Can anyone explain this with a small example or direct me to a similar question. Thank you in advance. Relations

+3


source to share


4 answers


The keyword friend

provides access to protected

and private

members class

. It is not used in your example because these functions do not need to use internals string

; the interface is enough public

.

friend

functions are never members of a class, even if they are defined within scope class {}

. It's pretty confusing. Sometimes friend

used as a trick to define a non-member function within parentheses class {}

. But in your example, nothing special happens, just two functions. And functions are operator overloads.



Bad style of defining some operator+

overloads as members and others as non-member. The interface will be improved due to the fact that they are all non-members. Different type conversion rules apply to the left argument, which becomes this

inside the overload function, which can cause confusing errors. Therefore, commutative operators usually have to be non-member ( friend

or not).

+2


source


Tell us about the + operator. If it is not a member, it can use the following code

string s1 = "Hi";
string s2 = "There";
string s3;

s3 = s1 + s2;
s3 = s1 + "Hi";
s3 = "Hi" + s1;

      

The last assignment operator is not possible if the + operator is a member and not a function of the namespace scope. But if it is a namespace scope function, the string literal "Hello" is converted to a temporary string object using the "string (const char *)" conversion constructor; and passed to the + operator.

In your case, it was possible to get by without making this function a friend, since you have auxiliaries for the private member's "buf". But usually, if such accessors are not provided for any reason, these namespace scope functions should be declared friends.

Now let's talk about the operator <



It is an input operator defined for ostream objects. If they have to print objects of a certain type, then the definition of the ostream class needs to be changed, which is not recommended.

Hence, the operator is overloaded in namespace scope.

In both cases, there is the well-known principle of Dependent Search Argument , which is the main reason these namespace scope functions look for, also called Koenig lookup.

Another interesting post: The principle of the namespace interface

+2


source


Operators can be overloaded with member functions and stand-alone (regular) functions. Whether the standalone overload function is a friend or not is completely irrelevant. Friendly ownership has absolutely nothing to do with operator overloading.

When using a stand-alone function, you may need to directly access the "hidden" (private or protected) internals of the class, that is, when you declare the function as friend

. Unless you need this kind of privileged access (that is, you can implement the required functionality in terms of the public interface of the class), there is no need to declare the function as friend

.

That's all.

Declaring a standalone overload function as a friend has become so popular that people often refer to it as "friend function overloading." This is indeed a misleading misnomer, because, as I said above, friendship itself has nothing to do with it.

Also, people sometimes declare an overloading function as friend

even though they don't need privileged access to the class. They do this because a function declaration friend

can include an inline function definition directly inside the class definition. Without friend

it, a separate declaration and a separate definition would have to be made. In some cases, a compact inline definition may look "cleaner".

+1


source


I'm a bit rusty with C ++ overloads, but I would fill the above answers with this simple note:

  • If the type of the left operand is a user-defined type (such as a class), you need (but not required) to implement the overloading operator as a member function. And keep in mind that if these overloads - which are likely to be like +, + =, ++ ... - modify the left operand, they return a reference to the calling type (actually on the modified object) .That's why, for example The Coplien overload, in canonical form, operator=

    is a member function and returns "UserClassType &". (because the function actually returns *this

    ).

  • If the type of the left operand is a system type ( int

    , ostream

    etc.), you must implement operator overloading as a stand-alone function.

By the way, I've always been told that the keyword is friend

bad, ugly and eating kids. I guess this is mainly a question of coding style, but I would therefore advise you to be careful when you use it and avoid it whenever you can. (I've never come across a situation where using it was mandatory, so I can't tell!)

(And sorry for my bad english, i'm a little rusty too)

Scy

0


source







All Articles