I'm a bit confused about what exactly this line of code means in my header file.
friend ostream & operator << (ostream &, const something &);
Can someone clarify for me?
That line of code says that the operator << is a friend of something (since it's listed in the something class definition). This means that that operator << function can access the variables inside there.
The & here as the parameters mean that you pass in objects when calling the method and those parameters will just be another name for those parameter objects. Returning ostream & means that you're going to return the ostream parameter so that you can connect << expressions together avoiding creating a new "cout" when using the one global cout is what is needed.
As mentioned in many places, friend is a bypass to the normal protection mechanisms of C++ - it allows the function in question to access protected/private members, which normally only class members can do.
You'll often seen operators declared friends, because operators are never inside the class itself, but often need to modify something in the class and/or access private information. I.E. you may not want an external function to be able to muck with your internal pointers etc, but you may want to be able to print them out for status etc. You don't see them used very often otherwise - technically, it breaks encapsulation - but operators are kind of a special case.
A C++ class may declare another class or a function to be a friend. Friendly classes and methods may access private members of the class. So, the free operator method <<, not defined in any class, may insert somethings into a stream and look at and use the private members of something to do its work. Suppose something were complex:
class complex {
private:
double re;
double im;
public:
complex(double real = 0.0, double imag = 0.0) : re(real), im(imag) {}
friend ostream & operator<<(ostream& os, complex& c);
};
ostream & operator<<(ostream& os, complex& c){
os << c.re << std::showpos << c.im;
return os;
}
The friend keyword can name either functions or entire classes. In either case, it means that the implementation of the named function, or the named class, is allowed to access private and protected members of the class in which the friend declaration appears.
In this case, it means that this particular overload of the operator<< function is allowed to access internals of the something class, in order to write then to an output stream such as std::cout.
Related
I have a class that represents a special number.
class SecretInteger
{
private:
unsigned int *data;
size_t length;
public:
SecretInteger operator+(const SecretInteger other) const;
}
I can't allow any other part of my code have access to the data variable. However, my operator+ function MUST be able to see it. Usually in this case I know that using the friend keyword is the only way to do it. However when I write:
friend SecretInteger operator+(const SecretInteger other);
It claims that the operator+ cannot be declared as friend, even though I've previously wrote friend std::ostream& operator<<(std::ostream& stream, const SecretInteger val); and it works fine.
What options do I have available to me? If I have a public method like
const *unsigned int getData() const; I think even then it doesn't actually make the variable returned const right? I'd really prefer not to have a getData() method and instead just declare the functions that have access as friend.
You don't declare a member function as a friend, friend is to give non-member functions access to internals, and a one operand overload of operator+ is a member function.
In any event, if you implement the binary operators properly, you shouldn't need to give out friendship at all. Implement += as a member function (no need for friend, a class is always "friends" with itself), then implement a non-member + operator in terms of +=, which uses +='s access to the internals to avoid the whole issue of friendship.
The basic rules for overloading can be found here and should help a lot.
Following is the abstraction of 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 operator overloaded functions
string operator+(const char *, const string &);
std::ostream& operator<<(std::ostream&, const string&);
are not class member function or friend functions? I know the two parameter operator overloaded functions are generally friend functions (I am not sure, I would appreciate if you could enlighten on this too) however my prof did not declare them as friend too. Following are the definitions of these function.
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();
}
Could anyone explain this with a small example, or direct me to similar question. Thanks in Advance.
Regards
The friend keyword grants access to the protected and private members of a class. It is not used in your example because those functions don't need to use the internals of string; the public interface is sufficient.
friend functions are never members of a class, even when defined inside class {} scope. This is a rather confusing. Sometimes friend is used as a trick to define a non-member function inside the class {} braces. But in your example, there is nothing special going on, just two functions. And the functions happen to be operator overloads.
It is poor style to define some operator+ overloads as members, and one as a non-member. The interface would be improved by making all of them non-members. Different type conversion rules are applied to a left-hand-side argument that becomes this inside the overload function, which can cause confusing bugs. So commutative operators usually should be non-members (friend or not).
Let's talk about operator +. Having it as a non member allows code such as the following
string s1 = "Hi";
string s2 = "There";
string s3;
s3 = s1 + s2;
s3 = s1 + "Hi";
s3 = "Hi" + s1;
The last assignment statement is not possible if operator+ is a member rather than a namespace scope function. But if it is a namespace scope function, the string literal "Hi" is converted into a temporary string object using the converting constructor "string(const char *);" and passed to operator+.
In your case, it was possible to manage without making this function a friend as you have accessors for the private member 'buf'. But usually, if such accessors are not provided for whatever reason, these namespace scope functions need to be declared as friends.
Let's now talk about operator <<.
This is the insertion operator defined for ostream objects. If they have to print objects of a user defined type, then the ostream class definition needs to be modified, which is not recommended.
Therefore, the operator is overloaded in the namespace scope.
In both the cases, there is a well known principle of Argument Dependent Lookup that is the core reason behind the lookup of these namespace scope functions, also called Koenig Lookup.
Another interesting read is the Namespace Interface Principle
Operators can be overloaded by member functions and by standalone (ordinary) functions. Whether the standalone overloading function is a friend or not is completely irrelevant. Friendship property has absolutely no relation to operator overloading.
When you use a standalone function, you might need direct access to "hidden" (private or protected) innards of the class, which is when you declare the function as friend. If you don't need this kind of privileged access (i.e. you can implement the required functionality in terms of public interface of the class), there's no need to declare the function as friend.
That's all there is to it.
Declaring a standalone overloading function as friend became so popular that people often call it "overloading by a friend function". This is really a misleading misnomer, since, as I said above, friendship per se has nothing to do with it.
Also, people sometimes declare overloading function as friend even if they don't need privileged access to the class. They do it because a friend function declaration can incorporate immediate inline definition of the function right inside the class definition. Without friend one'd be forced to do a separate declaration and a separate definition. A compact inline definition might just look "cleaner" in some cases.
I'm a bit rusty with C++ overloads but I would complete the above answers by this simple memo :
If the type of the left-hand operand is a user-defined type (a class, for instance), you should (but you don't have to) implement the operator overloading as a member function. And keep in mind that if these overloads -- which will most likely be like +, +=, ++... -- modify the left-hand operand, they return a reference on the calling type (actually on the modified object). That is why, e.g. in Coplien's canonical form, the operator= overloading is a member function and returns a "UserClassType &" (because actually the function returns *this).
If the type of the left-hand operand is a system type (int, ostream, etc...), you should implement the operator overloading as a standalone function.
By the way, I've always been told that friend keyword is bad, ugly and eats children. I guess it's mainly a matter of coding style, but I would therefore advice you to be careful when you use it, and avoid it when you can.
(I've never been faced to a situation where its use was mandatory yet, so I can't really tell ! )
(And sorry for my bad English I'm a bit rusty with it too)
Scy
Which C++ operators can not be overloaded at all without friend function?
You only need a friend declaration if:
You define the operator as a standalone function outside the class, and
The implementation needs to use private functions or variables.
Otherwise, you can implement any operator without a friend declaration. To make this a little bit more concrete... one can define various operators both inside and outside of a class*:
// Implementing operator+ inside a class:
class T {
public:
// ...
T operator+(const T& other) const { return add(other); }
// ...
};
// Implementing operator+ outside a class:
class T {
// ...
};
T operator+(const T& a, const T& b) { return a.add(b); }
If, in the example above, the "add" function were private, then there would need to be a friend declaration in the latter example in order for operator+ to use it. However, if "add" is public, then there is no need to use "friend" in that example. Friend is only used when granting access is needed.
*There are cases where an operator cannot be defined inside a class (e.g. if you don't have control over the code of that class, but would still like to provide a definition where that type is on the left-hand side, anyway). In those cases, the same statement regarding friend declarations still holds true: a friend declaration is only needed for access purposes. As long as the implementation of the operator function relies only on public functions and variables, a friend declaration is not needed.
The operators where the left-hand-side operand is not the class itself. For example cout << somtething can be achieved via defining a std::ostream& operator<<(std::ostream& lhs, Something const & rhs); function, and marking them as friend inside the class.
EDIT: Friending is not needed, ever. But it can make things simpler.
The only reason to use friend function is to access the private(including protected) member variable and functions.
You never need a friend function. If you don't want the operator to
be a member (usually the case for binary operators which do not modify
their operands), there's no requirement for it to be a friend. There
are two reasons one might make it a friend, however:
in order to access private data members, and
in order to define it in the class body (even though it is not a
member), so that ADL will find it
The second reason mainly applies to templates, but it's common to define
operators like + and - in a template base class, in terms of +=
and -=, so this is the most common case.
Operator overloading and friendship are orthogonal concepts. You need to declare a function (any function) friend whenever it needs access to a private member of the type, so if you overload an operator as a function that is not a member and that implementation needs access to the private members, then it should be friend.
Note that in general it is better not to declare friends, as that is the highest coupling relationship in the language, so whenever possible you should implement even free function overloads of operators in terms of the public interface of your type (allowing you to change the implementation of the type without having to rewrite the operators). In some cases the recommendation would be to implement operatorX as a free function in terms of operatorX= implemented as a public member function (more on operator overloading here)
There is an specific corner case, with class templates, where you might want to declare a free function operator as a friend of the template just to be able to define it inside the template class, even if it does not need access to private members:
template <typename T>
class X {
int m_data;
public:
int get_value() const { return m_data; }
friend std::ostream& operator<<( std::ostream& o, X const & x ) {
return o << x.get_value();
}
};
This has the advantage that you define a single non-templated function as a friend in a simple straightforward way. To move the definition outside of the class template, you would have to make it a template and the syntax becomes more cumbersome.
You need to use a friend function when this is not the left-hand-side, or alternatively, where this needs to be implicitly converted.
Edit: And, of course, if you actually need the friend part as well as the free function part.
operators [] -> =
Must be a member functions.
Other binary operators acceptable for overloading can be write in function form or in memeber-function form.
Operators acceptable for overloading is all unary and binary C++ operators except
: . :: sizeof typeid ?
In Ojective-C there is something called Categories which allow the user to add methods from outside the original .h or .m file (objective-c's version of .cpp)
I wonder if there exist such functionally in C++.?
I specially want implement << operator for debugging and maybe others of a class that is in a library I frequently use. (And don't want to use macros since it looks ugly ;) )
Thanks.
You could always overload operators outside of the class.
std::ostream& operator<< (std::ostream& f, const YourClass& cls) {
...
}
You still need to friend this function if it needs to access private members of YourClass.
(But it's not possible to define normal member functions like what Objective-C does.)
Yes, it's possible to add an overload for operator << outside of the class:
ostream& operator <<(ostream& lhs, const SomeClass& rhs) {
/* Output something to lhs using rhs object */
return lhs;
}
The only problem with this is that the function won't have access to SomeClass' private/protected members; to do that you must declare this function a friend inside the class. But if you get all the required information through the public interface, then it's not an issue.
Yes, the Namespace principle is almost similar to this. The idea is to have closely related class operations outside the class in the same namespace as the class. Operator overloading as #KennyTM suggested is a fallout of this principle (the way I look at it)
Also look at the visitor design pattern
Intent
Represent an operation to be
performed on the elements of an object
structure. Visitor lets you define a
new operation without changing the
classes of the elements on which it
operates.
I feel I have a bit of a hole in my understanding of the friend keyword.
I have a class, presentation. I use it in my code for two variables, present1 and present2, which I compare with ==:
if(present1==present2)
Here's how I defined the operator == (in class presentation):
bool operator==(const presentation& p) const;
However, I was told that using friend and defining it outside of the class is better:
friend bool operator==(presentation&, presentation&);
Why? What's the difference between the two?
Your solution works, but it's less powerful than the friend approach.
When a class declares a function or another class as friend it means that friend function or class have access to the declaring class' privates and protected members. It's as if the declared entity was a member of the declaring class.
If you define operator==() as a member function then just like with the friend case the member function has full access to the class' members. But because it is a member function it specifies a single parameter, as the first parameter is implied to be this: an object of type presentation (or a descendent thereof). If, however, you define the function as a non-member then you can specify both parameters, and this will give you the flexibility of comparing any two types that can cast into a presentation using that same function.
For example:
class presentation {
friend bool operator==(const presentation&, const presentation&);
// ...
};
class Foo : public presentation { /* ... */ };
class Bar : public presentation { /* ... */ };
bool operator==(const presentation& p1, const presentation& p2)
{
// ...
}
bool func(const Foo& f, const Bar& b, const presentation& p)
{
return f == b || f == p );
}
Lastly, this raises the question "why the friend declaration?". If the operator==() function does not need access to private members of presentation then indeed the best solution is to make it a non-member, non-friend function. In other words, don't give a function access privileges which is doesn't need.
In the first case, your function operator== is a nonstatic class member. It has therefore access to private and protected member variables.
In the second case, the operator is externally declared, therefore it should be defined as a friend of the class to access those member variables.
An operator implemented as a method, can only be called, if the left hand side expression is a variable (or a reference to the object) of the class, the operator is defined for.
In case of an operator== usually you are interested in comparing two objects of the same class. Implementation, as a method solves your problem here.
Imagine however, that you write a string class and you want an operator, to work in this scenario:
const char *s1 = ...
MyString s2 = ...
if(s1 == s2){...
To make the expression s1 == s2 legal, you have to define an opetator== as a function external to MyString class.
bool operator==(const char *, const MyString&);
If the operator needs an access to the private members if your class, it has to be a friend of your class.
In case of operators << and >>, that work on streams, you define an operator, whose left operand is a stream instance and the right one is your class, so they can't be methods of your class. Like in the example above, they have to be functions external to your class and friends, if the access to private members is required.
I like Benoit's answer (but I can't vote it up), but I figure an example wouldn't hurt to clarify it. Here's some Money code I have (assume everything else is placed right):
// header file
friend bool operator ==(const Money, const Money); // are the two equal?
// source file
bool operator ==(const Money a1, const Money a2)
{
return a1.all_cents == a2.all_cents;
}
Hope that helps.
Take a look at this sorta duplicate here: should-operator-be-implemented-as-a-friend-or-as-a-member-function
What is important to point out, this linked question is about << and >> which should be implemented as friends since the two operand are different types.
In your case it makes sense to implement it as part of the class. The friend technique is used (and useful) for cases where more than one type is used and often does not apply to == and !=.