Why isn't it possible to overload the subscript operator (operator[]) as a friend function?
As Bjarne Stroustrup says in the D&E book:
However, even in the original design of C++, I restricted operators [], (), and -> to be members. It seemed a harmless restriction that eliminated the possibility of some obscure errors because these operators invariably depend on and typically modify the state of their left-hand operand. However, it is probably a case of unnecessary nannyism.
Friends are not extensions to your class, just a keyword saying xy has access to your class's private or protected members. You can not override or add functions this way.
The friend declaration appears in a class body and grants a function or another class access to private and protected members of the class where the friend declaration appears.
Source
Related
In our C++ programming class, professor is using "friend" keyword to overload operators. However, when I search on the internet, most people don't use "friend" keyword. So, do we need to use "friend" keyword for operators? Is there such a rule or not?
If you define the operators within your class, they automatically have acces to the private parts of the objects involved. Not all operators should be defined as part of the class, though. In those cases where you define the operators outside of your class they need to be declared as a friend if they need to be able to access the private parts of the objects.
Why we always say that friend function are not member function even though they are declared in the class?
I have found in many books and on internet but i am not getting proper explanation.
friend (C++)
If you declare a friend function that was not previously declared,
that function is exported to the enclosing nonclass scope.
In [class.mfct] the C++ standard says (or said around the time of C++11. The link's bit out of date at this point)
Functions declared in the definition of a class, excluding those declared with a friend specifier ([class.friend]), are called member functions of that class.
I'm having difficulty finding similar wording in later drafts of the standard.
That said, I consider this one self-evident.
[class.friend] states:
A friend of a class is a function or class that is given permission to use the private and protected member names from the class. A class specifies its friends, if any, by way of friend declarations. Such declarations give special access rights to the friends, but they do not make the nominated friends members of the befriending class.
A friend is something outside the class that has been granted access by the class to the protected and private members of the class. This implies that a friend is not a member itself.
Note also that the friend function does not have to be implemented within the class. A declaration is sufficient.
Conceptually, a member function is of type Ret(Class::*)(Args...), is called on an instance of the class: instance.member_function(), and has access to the called instance via this. A friend function doesn't fit with "member functions". The function is defined in a separate scope and not in the class even though it looks similar to a member function declaration.
I would like to know if there is anything similar to a "friend function", from C++, in Fortran. I would like to be able to make operator overloading without creating new objects since it is too expensive. I have already tried creating objects in a module and trying to make the overloaded operator return it, but it was not successful.
Your understanding of what friend means in C++ is incorrect. That deals with the accessibility of private class members inside the friend function - not with object creation as part of operator overloading. Fortran's accessibility model is different - any procedure defined in the same module as a type is a "friend" and there is nothing equivalent, in accessibility terms, to a member function.
The semantics of expression evaluation in both languages requires that the source implementation of an operator create a new object to store the result of the operation. Fancy compiler optimisation may prevent the actual creation of a temporary for a function result in some cases, but that very much depends on details.
I've pored over information regarding friend functions and their use. They're able to access encapsulated data within a class while not breaking one of the golden rules of OOP. In purveying various source code for overloading the I/O operators (A basic operation, one of the first taught in learning C++) every one defines the operator as a friend as implements it outside of the class. My question is: does this need to be done? Why not just declare the function as a public member of the class and insert/display data from the class while keeping everything encapsulated? It seems no different than overloading other operators, yet it is a supposedly traditional approach to overloading the I/O operators.
Thanks for your time.
Let's say you want to overload operator<< for your class X, so you can use it like this:
X x;
std::cout << x;
Notice that std::cout is the first operand of the operator. To implement this as a member function, it would have to be a member of std::basic_ostream, which is the type of std::cout. You can't add members to an already defined class. That's why we declare it as a free function instead.
If you overloaded operator<< as a member of X, it would be taking an X object as its first operand, so you would use it like this:
X x;
x << something;
This is obviously not what you want when dealing with I/O.
If you have an overloaded operator like: a # b implemented as a member function, that call is translated to a.operator#(b);. That means the function must be a member of the class that's the type of the left operand. In the case of iostreams, that would be all the operators needed to be members of the iostream itself.
While iostreams do provide some insertion/extraction operators as members, you normally want to be able to add more without modifying the iostream class itself1. To do that, you pretty much need to implement the operator as a free function instead of a member function. Since you normally still want it to have access to the private parts of whatever type you're planning to read/write (insert/extract, if you prefer) it typically has to be a friend of that class.
This is an example of the so-called open/closed principle: the class should be open to extension, but closed to modification. In other words, you want to extend it without modifying it.
In "The C++ programming language", at page 265, the author makes the following statement:
Because of historical accident, the operators = (assignment), & (address-of), and , (sequencing;
ยง6.2.2) have predefined meanings when applied to class objects. These predefined meanings can
be made inaccessible to general users by making them private:
Then the following example is given:
class X {
private:
void operator=(const X&);
void operator&();
void operator,(const X&);
// ...
};
void f(X a, X b)
{
a = b; // error: operator= private
&a; // error: operator& private
a,b; // error: operator, private
}
I can't quite understand what do these "error" comments refer to? Does that mean I should not define a function like f, or that all of the =, &, and , operators should be used according to the default way, and it is not necessary to redefine them?
This example simply shows a way to prevent yourself or other developers of the code from using operators, which can be used without having been defined in the class, because they're automatically generated (and have default meanings for the operations they represent).
The author of the example meant, that if you try to assign b to a (in line a = b) it will cause an error, because the assignment operator is private in the class definition.
Similar error occurs in case of address-of in the second line, and the comma operator in the third.
Making default operators/constructors private if you know they're not supposed to be used (or haven't been implemented yet) is good, because one may accidentally use a very frequent operator like assignment or copy-constructor, being unaware that it's default behavior conflicts with the class lifecycle. If such operator or constructor is made private at the very beginning of class design, the compiler will generate a compile-time error instead of performing a potentially dangerous operation without notice if the programmer accidentally uses the method.
Think default assignment operator and member pointer: it will copy the pointer whereas you might want the object to be the owner of data. Then, after someone assigns one object to another without knowing that assignment is not implemented, you will end up with a double free error. Instead of that, if the operator is private, you'll get a nice error and the code will not even compile, and you'll know what's going on.
The author intends to point out here that the operators =, & and , are usually implicitly available for a class.
So if you don't want your objects to be operated on through them then you declare them as private thus disallowing their use.
Since they are declared as private you cannot access them anymore outside the class and the compiler gives you a compilation error. The function is an example showing that.
Providing your own implementation of any operator is basically the same as implementing a class method. Operators and methods are the same in terms of accessibility. What you do is disallowing access to operators from the caller's code.
It's absolutely the same as if you defined a private method and then tried to call it from some code that is not part of your class. Just make the operators public and errors will go away.
It basically prevents any one from making an 'X' object and using the "=", "&", and "," operators on that class. Because the author of the class may implement those objects with a meaning that is quite different to what the consumer of the class might think they do ... so its best to prevent them being used at all in the case of ambiguity.
The function f is an example of a user trying to use the private operators. It shows you what code it is that you're preventing by making them private. The comment // error means that a program that contained that line would fail to compile for the stated reason.
Before discussing the error, a key here is to understand that these operations will be implicitly made available for your class. This is the essence of Scott Meyers' advice "Know what functions C++ silently writes and calls."
C++ will automatically implement the assignment operator for your class, but it may not be done correctly (for example, if your class contains a pointer member variable). By defining the assignment operator explicitly, you are telling the compiler to use your implementation instead of generating one for you. And by making it private, you are essentially disallowing assignment of one class instance to another. Anywhere you try to do this in your code, the compiler will complain, which is a good thing if you really don't want assignment to be done.
In function f the author is showing you that these statements will not compile because of how the operators are defined in the class. It is perfectly acceptable to redefine operators for your class, and sometimes it is definitely required (for example, to implement a deep copy of a pointer member variable in your class). The point of the example is to show that a) you can provide your own implementation of these operators for your class, and b) because of this you have control over whether the operators are supported and implemented correctly for your class.