C++ operator overloading with "friend" keyword - c++

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.

Related

Operator[] overloading using friend function

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

Operator overloading in Fortran with no object creation such as in friend functions (C++)

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.

Friend functions and their relationship to the I/O Operators

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.

C++ static-only class

I have a bunch of functions that I want to put in either a separate namespace or a class. Out of the two, which would be better? If it's the latter, how should I go about it? I mean, I don't have any instance members, so should I specify the constructor as private? Or delete it?
Either way, it will look something like this to give you an idea:
myproject::foo::f()
C++ namespaces and class can both contain functions and other types, but there are some key differences in behavior. You'll have to decide which is best for your particular circumstance.
Classes can be templated, namespaces can't. This provides a way to pass a set of template arguments to a whole group of functions and other types. Combined with typedef, this can be very powerful.
You can use using namespace xyz; to bring a whole group of namespace members into any scope. Classes can be inherited to bring them into scope (has not much effect if there are no instance members, due to the empty base optimization, but static members can then be used without qualification), but this only works inside other classes. Free functions would have to explicitly qualify all access to members of the class.
Namespaces participate in argument-dependent lookup, members of a parent class don't.
If you want to use the trick of inheriting a class to supply template arguments and gain unqualified access to its static members, then you should leave the constructor and destructor as defaulted and trivial, instead of deleting or making them inaccessible. In C++11, you can mark the constructor both protected and defaulted.
If you use the class it is best to declare the default constructor, copy constructor, assignment operator, and destructor private / unimplemented (plus maybe some more for C++11). If you don't you'll have a class that can be used to make useless objects. If you use a namespace you don't have to do any of that.
Classes are made for objects. Using them as containers of static functions, no member data, is more abuse than use.

Question on predefined meanings for operators

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.