Designating functions as Friend C++ - c++

I'm looking at the following documentation
https://en.cppreference.com/w/cpp/language/friend
The first Syntax example (friend function-declaration) has me confused
It says:
Designates a function or several functions as friends of this class
class Y
{
int data; // private member
 
// the non-member function operator<< will have access to Y's private members
friend std::ostream& operator<<(std::ostream& out, const Y& o);
friend char* X::foo(int); // members of other classes can be friends too
friend X::X(char), X::~X(); // constructors and destructors can be friends
};
 
// friend declaration does not declare a member function
// this operator<< still needs to be defined, as a non-member
std::ostream& operator<<(std::ostream& out, const Y& y)
{
return out << y.data; // can access private member Y::data
}
my confusion comes with the following line of code friend char* X::foo(int); // members of other classes can be friends too. I don't know why would we want to declare such a function since I don't see any use to giving friendship to a member function of another class ( class X in this case) since we are not passing a class Y reference object as an argument, so we can't really access Y's private member via the foo function.
Is there an use case where this example could be useful ?

I would like to start by noting that not everything permitted by the C++ standard is necessarily useful. Sometimes things are allowed because they do no harm and forbidding them would make the standard more complicated. In these cases, the standard tends to prefer simplicity, which implies being permissive.
Sometimes, this permissiveness is itself useful because eventually someone finds a use for the allowed thing that had appeared useless. So inquiring about usefulness can be productive. Questions like this one are good for the growth of knowledge, as long as one does not get too hung up on them. Sometimes examples are just examples of what is possible, not of what is (known to be) useful.
Now on to the case at hand.
Let's suppose that X has a member of type Y. It could be reasonable to give X access to the data of Y. For example, the definition of X might look like the following. (The use of unique_ptr is to avoid a circular dependency problem – the definition of X needs to occur before the definition of Y.)
class Y; // Forward declaration
class X
{
std::unique_ptr<Y> token;
public:
X(char);
~X();
char* foo(int);
Y getToken();
void giveToken(Y);
};
In this setup, with friendship, the constructor would be able to set token->data to whatever value is desired, foo() would be able to change that value, and the destructor could read that value.
While this much gives a reason for the friend declarations, so far replacing Y with a private nested class would do as well. That's why I added the getToken() and giveToken() members. I could see this class giving away copies of *token for consumers to hold. Think of this as taking a snapshot. Since the consumers are not friends of Y, the token is effectively immutable to them. They can copy it, move it, discard it, but not modify it. (If the Y constructor was made private, consumers also would be unable to create new tokens.)
Later, the token could be given to an object – not necessarily the same object, not necessarily an X object – perhaps to reset its internal state to the snapshot. (This can be done without friendship if it can be accomplished via *pimpl = y;.) If there are multiple classes that can process these tokens, there is reason to make Y an independent class rather than a nested class.
I do not claim this is a good design, but it is a valid one.

Related

unconventional uses of friend in c++

I know the general use cases for the friend keyword with regards to encapsulation but one a couple of occasions, I have needed the friend keyword just to "get the job done". These use cases don't make me happy so I'm wondering if there are some alternatives. Here's the first minimal example:
struct Foo{
enum class Bar{
a=1,b=2,c=4
};
// need to tell the compiler of operator| before it gets used
// but it can't be a member function of Foo: so add friend keyword
friend Bar operator|(const Bar& b1, const Bar& b2);
// constructor needs a default value using
// operator| for Bars
Foo( Bar b = Bar::a | Bar::b );
};
// definition of operator|, etc.
Is there any way for the compiler to see the declaration of the operator| for the nested class, inside of interface, before the default values are given at the Foo constructor declaration?
I also sometimes find myself using the friend keyword in defining symmetric operations of nested classes within templates. For example:
template<typename T>
struct A{
struct B{
friend bool operator==(const B& x, const B& y) { return true; }
};
};
The operator== does not require friendship from an encapsulation perspective. But due to operator== not actually being a templated function and the compiler being unable to deduce the types of nested classes within templates, this seems to be the only reasonable "trick" to keep operator== as a free function.
As I said, these choices do work, but I'm wondering if there are better choices/practices out there.
In fact, I would say it's perfectly conventional. While, as mentioned by Evg, hidden friends have special benefits, visible friends are also great to have!
To make this more of an answer, consider for example libstdc++'s implementation of std::unreachable_sentinel_t. This can be returned as the end() of an unbounded "generator range", such as a std::ranges::iota_view{0}. It's very similar to your second example:
struct unreachable_sentinel_t
{
template<weakly_incrementable _It>
friend constexpr bool
operator==(unreachable_sentinel_t, const _It&) noexcept
{ return false; }
};
inline constexpr unreachable_sentinel_t unreachable_sentinel{};
Regular iterators and sentinels are defined as nested classes and also rely on friendship, though their comparison operators typically do need the privileged access. However, even if you could provide an out-of-line definition, an additional benefit of inlining friends in templates is that you don't have to repeat the exact template header, including potentially complicated constraints.
If it helps, in C++ you can think of free functions like these, whether or not they are friends, as being part of the public interface of the classes of their arguments, due to argument-dependent lookup. As such, even if you don't technically need the privilege of friendship, granting it does not break encapsulation.
As long as you're aware of the nuance of hidden friendship, just use friend if it gets the job done!

Is private const redundant in a C++ class?

Suppose I have a class with a member variable that I don't want to be changed. Is there any difference between making that variable a private const and just making the variable private, assuming there is no setter function?
Private:
class ConstFoo
{
public:
Foo(int a);
virtual ~Foo();
int val(){ return val_; }
private:
int val_;
}
Private Const:
class ConstFoo
{
public:
Foo(int a);
virtual ~Foo();
int val(){ return val_; }
private:
const int val_;
}
It seems that there is no difference between the two, since you can't change the value of val_ in either case, so the const qualifier seems redundant.
The one reason I can see to explicitly add const is for code clarity, so people working on the code in the future don't add a setter to the function. However, with the name as ConstFoo and documentation specifically stating that it is not meant to be mutable, I don't think this will be an issue.
It's all a matter of how "const" you want this value to be.
As it currently stands, no external user can directly change the value. But they can do so indirectly, because the object itself may not be const:
ConstFoo a{0};
ConstFoo b{2};
a = b;
a now has 2 in it.
Plus, code within ConstFoo can change its value too; this is why the copy assignment operator can change its value.
So if you want to ensure that the specific member object will assume one value throughout the lifetime of any ConstFoo instance, you declare it const.
Of course, this makes ConstFoo non-assignable.
You correct that no outsider can change the member if it is private. This does not mean though that it can't be changed. If you had another member function like
void bar() { val_ = 42; }
Then your first code block would compile while the second one would give you an error. If you truly do not want to be able to change the value of the member then it should be const regardless if it is private or not. That const will act as a bug checker for you.
You've pretty much answered it yourself: making it const expresses your intention very clearly, and give the compiler the ability to back you up.
In my humble opinion, the const keyword serves two purposes:
A) It shows the programmers intent that this value is not to be changed once it's been set,
B) It allows the compiler to enforce that intent, thereby preventing mistakes.
Naming it constFoo somewhat achieves the first of these but does nothing for the second. And is (again IMHO) significantly more ugly than using const.
Not sure, if i get your question right, but generally speaking:
private members can only be accessed from inside the class itself, whereas public members can be accessed from the outside
const members can only be set once inside the constructor when creating a new object of this specific class
That means, a private const variable could be set once when creating a new object of this class and could therefor act as an internal modifier (e.g. giving a offset to certain functions provided by that class) valid over the whole lifetime of this object.
A mere private variable could change its value from inside the class and therefor.
Also generally speaking you are completely right, the whole concept of using constants in C++ is for making sure, your constraints are complied to in the further development process (not only by other developers, also by yourself)
The private keyword makes sure noone outside the class can modify the variable.
If you don't modify the variable inside the class then the result is the same.
As my opinion it is better to use the keywork const too because not only it is telling to the developers (including yourself) who might modify your class that it is intended to remain constant but it is also more secure: if they try modify the modification will not have effect.
So in my opinion it is not redundant.

Why is it recommended to declare functions as "friends" in operator overloading [duplicate]

This question already has answers here:
Operator overloading : member function vs. non-member function?
(2 answers)
Closed 8 years ago.
I have read this at many places which recommend of using "friend" while overload operators but no body explained it clearly as to why it is really needed? Why can not we declare them as plain member function? Any shortcoming?
Googled this but did not get any clear answer.
Sometimes you can't declare operator overload as a member function, like in IO operator<< and operator>>. The first parameter of these functions has to be ostream or istream, which are library classes and you can't extend them, declaring such functions as friend gives them access to private variables of your class.
Using friend means it's a nonmember friend function.
For improving encapsulation by minimizing dependencies, it's better to declare nonmember nonfriend functions. If it need to access the private/protected member of the class, make it friend. At last, make it a member function.
Here's an algorithm to determine whether a function should be a member and/or friend, from [C++ Coding Standards: 101 Rules, Guidelines, and Best Practices By Herb Sutter, Andrei Alexandrescu](Item 44. Prefer writing nonmember nonfriend functions):
// If you have no choice then you have no choice; make it a member if it must be:
If the function is one of the operators =, ->, [], or (), which must be members:
Make it a member.
// If it can be a nonmember nonfriend, or benefits from being a nonmember friend, do it:
Else if: a) the function needs a different type as its left-hand argument (as do operators >> or <<, for example); or b) it needs type conversions on its leftmost argument; or c) it can be implemented using the class's public interface alone:
Make it a nonmember (and friend if needed in cases a) and b) ).
If it needs to behave virtually:
Add a virtual member function to provide the virtual behavior, and implement the nonmember in terms of that.
Else: Make it a member.
In some case, such as above-mentioned a) and b), you can't achieve them by member function, you have to declare them as nonmember function, and make them friend if need to access the private/protected member of the class.
There are a few reasons people use friend:
sometimes granting friendship is actually reasonable, as the public API shouldn't expose some members than need to be compared
it's convenient for a lazy programmer to grant access to all the private and protected data members, ensuring you can write the operator implementation without needing to go back to grant access later or use a less obvious/direct public function (that's NOT a good reason, just a lazy one)
you can define the operator function inside the class, where any template parameters, typedefs, constants etc. don't need to be explicitly qualified as they would in the surrounding [namespace] scope. That's considerably simpler for those new to C++.
e.g.:
template <typename T>
struct X
{
friend bool operator==(const X& lhs, const X& rhs) { ... }
};
...vs...
...struct X as above without ==...
template <typename T>
bool operator==(const X<T>& lhs, const X<T>& rhs) { ... }
in a two-birds-with-one-stone scoop, it makes the function nominally inline, avoiding One Definition Rule complications
Only the first reason above is a compelling functional reason for making the operator a friend, rather than making it a non-member function, given the lesser encapsulation and correspondingly higher maintenance burden involved.
There are excellent reasons though to prefer either a friend or non-friend non-member function to a member function, as an implicit constructor can then kick in to allow the operator to work with one instance of the class and another value from which a second instance can be constructed:
struct X { X(int); };
bool operator==(const X& lhs, const X& rhs);
x == 3; // ok for member or non-member operator==
3 == x; // only works for non-member operator== after implicit X(3) for lhs
You are listing two options only for overloaded operator, while actually there are three:
global function, not friend
member function
global function, friend of the class
You did not list the first one, and yet it is the recommended one. If you can define an operator in terms of existing class public interface, define it as global function outside the class. In this way you do not extend the class public interface without need, minimizing the number of functions with access to the class private members.
What to do if the operator needs to access the class private members? Then you have two options - member function or a friend global function. From those two member function is preferable because it is cleaner. However, in some cases it is not possible to define an overloaded operator as the member function. If the object of your class is right-hand argument to two-argument operator, then global function is the only choice.
I assume that we are comparing global-scope friends that are defined in class and non-friends.
The reasons that the former is sometimes preferred are that such functions...
... need access to the data members for the operation to be performed. This can also be done by loosening encapsulation by providing the data through public getters, but that's not always desired.
... shall only be found via ADL to avoid pollution of some namespaces and overload candidate sets. (Only friend functions that are defined in the class they are a friend of satisfy this!)
Moreover, a minor goodie is that for class templates, it's easier to define a global function that operates on specializations inside them since we avoid making the function a template. Also the function is implicitly inline. All this shortens the code, but is no primary reason.
If your implementation followed proper data encapsulation then you might not exposed your data variables to outside world and all data members will be declared as private.
But using operator overloading most of the times you will be accessing the data members , please note it here you will be accessing the data members outside your class. So to provide access to the data members outside your class it is advised to declare the operator overloaded function as friend.
But this might not be required for unary operators , as it will operate on the data members of the particular class in which it is called.
Let me know if you need any examples for your understanding.
There are serious advantages to non-member functions when dealing with operators.
Most operators are binary (take two arguments) and somewhat symmetrical, and with a member operator they only work if *this is the left-hand side argument. So you need to use a non-member operator.
The friend pattern both gives the operator full access to the class (and, operators are usually intimate enough that this isn't harmful), and it makes it invisible outside of ADL. In addition, there are significant advantages if it is a template class.
Invisible outside of ADL lets you do crazy stuff like this:
struct bob {
template<class Lhs, class Rhs>
friend bob operator+( Lhs&&, Rhs&& ) { /* implementation */ }
}
here our operator+ is a template that seemingly matches anything. Except because it can only be found via ADL on bob, it will only be matched if it is used on at least one bob object. This technique can let you pick up on rvalue/lvalue overloads, do SFINAE testing on properties of types, etc.
Another advantage with template types is that the operator ends up not being a template function. look here:
template<class T>
struct X {};
template<class T>
bool operator==( X<T>, X<T> ) { return true; }
template<class T>
struct Y {
friend bool operator==( Y, Y ) { return true; }
};
struct A {
template<class T>
operator X<T>() const { return {}; }
};
struct B {
template<class T>
operator Y<T>() const { return {}; }
};
int main() {
A a;
X<int> x;
B b;
Y<int> y;
b == y; // <-- works!
a == x; // <-- fails to compile!
}
X<T> has a template operator==, while Y<T> has a friend operator==. The template version must pattern-match both arguments to be a X<T>, or it fails. So when I pass in an X<T> and a type convertible to X<T>, it fails to compile, as pattern matching does not do user defined conversions.
On the other hand, Y<T>'s operator== is not a template function. So when b == y is called, it is found (via ADL on y), then b is tested to see if it can convert to a y (it can be), and the call succeeds.
template operators with pattern matching are fragile. You can see this problem in the standard library in a few points where an operator is overloaded in ways that prevent conversion from working. Had the operator been declared a friend operator instead of a public free template operator, this problem can be avoided.

C++ User Defined Class Copy Assignment Missing?

I have written two custom classes, called A and B
My B class has a member variable a, and it has a function:
void B::setA(A s)
{
a = s;
}
However, this line is giving me an error:
'operator =' function is unavailable in 'A'.
From my understanding, this means somehow the compiler is not creating a default copy assignment function for my A class. However, I don't see why... the only constructor I've written in A looks like...
class A
{
//...
public:
A() {};
//...
};
Now in truth, A and B are large classes with a lot of member variables, and the names aren't really A and B. Short of posting the entire source for both of these classes, could anyone tell me what types of things I might look for when trying to diagnose that error message? Just to be clear, I never use pointers or low-level features like that so, as far as I know, the default copy-assignment should work fine for class A.
edit:
Someone mentioned that one of the member variables of A might be to blame, so here are all of the types:
const std::string
static const bool
static std::map<int,std::string>
std::vector
std::map<int, C>
where C is a struct that I defined in the same header file that A is in. It just contains a few integers and strings.
You have in class A a non-static data member declared as
const std::string
that is with the qualifier const. In this case the implicit copy assignment operator is defined by the compiler as deleted.
const members don't mix well with copy assignment operators. Not only won't the compiler generate one for you, it would also be semantically hard to come up with an "assignment" which does not actually assign everything.
Nothing stops you from writing an assignment operator which does not assign to your const member, of course, but that would mean one of two things:
The assigned object does not appear to the client as an identical copy of the source, which is not what one would except from a copy assignment operator, so that would be a case of operator-overloading abuse.
The member variable does not have an observable effect to the outside. In that case, one must wonder why it exists in the first place, or rather why it is not mutable rather than const.

c++ why doesn't a copy of an object allow access to a private variable of the original?

For example,
Number operator+(Number a, Number b) {
return Number(a.x + b.x);
}
Would this cause some kind of "unable to access private member error". I understand that if I don't pass by reference, the Number a, and Number b are copied on the stack and used in the body of the function. However, I don't see why they do not allow access to the originals' private members. How am I misunderstanding the concept of an object? Also how come friend and member function don't need to pass by reference?
operator+ is an unbound function, i.e. it is not a member of Number so, this is the rule, it has no implicit access to private members.
The rule is not affected by you passing Number objects by value or by reference. Access protection is applied to every access to a Number object, even if it is your private, stack-based copy.
There are at least three ways out:
declare Number operator+(Number, Number) a friend of Number
add a public getter for x so the variable is accessible.
implement the += operator as a member of the class and implement the free operator in terms of it: return Number(a) += b;
You're definitely misunderstanding something. 'Pass by reference', 'copied on stack' etc. have absolutely nothing to do with the access rules.
The code above is an error because operator+ is not a member of Number, and (presumably) it's not a friend of Number either. So it cannot access private members. That's all there is to it.
As many have answered operator + is not a member of Number class, it is a global variable. Consider a function Show:
void Show(const Number& numberObj) // const, by-ref is IMMATERIAL
{
std::cout<< numberObj.x;
}
and a method Show:
class Number
{
private:
int x;
public:
void Show()
{
std::cout << x;
}
};
Now, if you replace Show with any overloaded operator, taking 1 or 2 arguments - only the class-member can access the private data, and global implementation cannot.
For this, you need to make global Show a friend of class (in class declaration), and likewise any globally implemented operator.