Nonmember functions that are part of the interface of a class should be declared in the same header as the class itself.
The upper quote came from the book C++Primer 5th ed. I wonder if there is a best practice to distinguish nonmember functions and member functions in the header file? Or this is not necessary at all?
Or put it this way:
As a designer of a class, is it necessary to tell the user in the header file that which function is only part of the interface and which one is member function?
The language syntax already distinguishes members from non members, both for definition and declaration.
Declarations
class Example
{
public:
void member(int); // member, inside the class definition
friend std::istream & operator>>(std::istream &, Example &); // non-member, marked with keyword friend
}
std::ostream & operator<<(std::ostream &, Example &); // non-member, outside the class definition
Definitions
void Example::member(int param) {} // Example:: qualification on the name
std::istream & operator>>(std::istream & is, Example &) { return is; } // no Example::
std::ostream & operator<<(std::ostream & os, Example &) { return os; } // no Example::
You can often lay the header out in sections, and give the group a heading, but the distinction is apparent from the syntax
Related
I want to display the details of an object of derived class using friend ostream& function of base class.How can we make that?How can I make member function and not a member function of class so that it can be used as virtual function and for displaying the details of object of derived class.
A stream inserter takes a stream as its first argument, so when the inserter is a member function it's a member of the stream class, not the class that you're writing. So it can't be a virtual function in your class. But it can call a virtual function in your class.
class my_class {
virtual std::ostream& put(std::ostream& out) const {
out << "here we go!\b";
}
friend std::ostream& operator<<(std::ostream& out, const my_class& my_object);
};
std::ostream& operator<<(std::ostream& out, const my_class& my_object) {
my_object.put(out);
}
I am very new to C++, and when I am trying to learn the friend function, I saw from friend description on Cppreference that:
2) (only allowed in non-local class definitions) Defines a non-member function, and makes it a friend of this class at the same time. Such non-member function is always inline.
class X {
int a;
friend void friend_set(X& p, int i) {
p.a = i; // this is a non-member function
}
public:
void member_set(int i) {
a = i; // this is a member function
}
};
Does this mean that all friend functions always have to be inline? In another word, must the friend functions be defined completely inside the class?
However, I also found an instance where the friend function is defined outside the class from Cplusplus
// friend functions
#include <iostream>
using namespace std;
class Rectangle {
int width, height;
public:
Rectangle() {}
Rectangle (int x, int y) : width(x), height(y) {}
int area() {return width * height;}
friend Rectangle duplicate (const Rectangle&);
};
Rectangle duplicate (const Rectangle& param)
{
Rectangle res;
res.width = param.width*2;
res.height = param.height*2;
return res;
}
I am really confused by this conflict. Is my understanding of inline wrong?
What does it mean by "a nonmember friend function defined inside the class is automatically inline"?
any function defined inside a class (member or non-member friend) is always implicitly inline. That's because class definitions are generally in header files, and you don't want any non-inline function definitions in a header file (having a non-inline function in a header leads to multiple definitions if the header is #included in more than one source file).
If you want a function to be non-inline, you need to define it outside of a class definition. If its a member or friend you still need to declare it inside the class, since members and friends must be declared in the class. You just don't want it defined in the class.
This all gets into the difference between a definition and a declaration in C++ -- they are two distinct things, though every definition is also implicitly a declaration, not every declaration is a definition. As a result, when the spec says 'declaration' it often means 'declaration that is not also a definition'
I am very confuse in getting the idea of operator overloading as a member and non member function.
What do we actually mean, when we overload operator as a non-member function and similarly what do we mean when we overload operator as a member functions. Although I know that the non-member functions are the friend functions.
If you overload an operator as a non-member function, you need to specify an object which you want to operate on specifically in your argument list.
If you overload it as a member function, the "this" pointer will do part of the work for you.
Consider the following example:
class Test {
public:
friend Test operator+(const Test &lhs, const Test &rhs); // Non-member function
Test operator+(const Test &rhs); // Member function
};
The difference between the two is that the non-member function doesn't have the this pointer that compiler conveniently passes for you whenever you're talking about a specific instance of a class.
The member function one has the lhs inferred, therefore you need to provide only the rhs.
Please do note that the "friend" is not necessary but if you want to access Test's private members, you need it.
Compiler can disambiguate based on the parameter count. If you wanted to declare friend Test operator+(const Test &rhs), it would complain about insufficiency of arguments because + is a binary operator. The lhs of a member function operator+ is "this".
example
class Foo {
public:
Foo operator+(Foo) // member variant
// declared inside the function
}; // end of class
Foo operator+(Foo lhs, Foo rhs) // non-member variant
{ // declared outside the class
// could be just a call to the member variant
lhs.operator+(rhs);
// I usually do this when implementing std::stream operators,
// don't remember why just now.
}
the non-member does not need to be friended but may be if it need access to internal state.
the non-member has some advantages when it comes to templated code and namespaces on some compilers if I remember correctly, It can also be fine to friend in the non-member variant to document that there is a function outside the class that is somewhat specific to this class. It tells me that if I change that class I may have to look over the non-member operator to make sure that I have not broken anything.
A small example: (I haven't tried compiling this code but I hope it works)
class MyClass
{
public:
MyClass operator+(const MyClass& other) const; //member operator declaration
friend MyClass operator-(const MyClass& first, const MyClass& second); //non-member operator friend declaration
private:
int _a;
}
//member operator definition
MyClass MyClass::operator+(const MyClass& other) const
{
MyClass result;
result._a = _a + other._a;
return result;
}
//non-member operator definition
MyClass MyClass::operator-(const MyClass& first, const MyClass& second)
{
MyClass result;
result._a = first._a - second._a;
return result;
}
Mind the differences: in the member operator definition I don't specify anything before the first _a after "=" - this->_a is assumed.
The member operator functions can be used only if an instance of your class is the first argument of the operator. If, for example you wanted to do something like 2 + myClassObject, you would need to override the non-member operator MyClass MyClass::operator+(int first, const MyClass& second) (or with whatever return value you want this to have).
Note also that I needed the friendship declaration only for my non-member operator to have an access to the private _a field.
Most operators should be defined as members.
class MyClass
{
...
public:
const MyClass& operator+=(const MyClass&);
};
Bit this is identical in behavior to the following:
class MyClass {...};
const MyClass& operator+=(const MyClass&, const MyClass&);
The implied this in the first example is analagous to the first parameter to the second example. If the second example needs access to the internal state of MyClass, it needs to be friended.
class MyClass
{
friend const MyClass& operator+=(const MyClass&, const MyClass&);
};
const MyClass& operator+=(const MyClass&, const MyClass&);
The prototypical exception to this is operator<< on std::ostream.
std::ostream& operator<<(std::ostream&, const MyClass&);
This is logically a member of your MyClass, but because of the ordering of the parameters it would have to be a non-member of both classes or a member of std::ostream. Because you can't add members to std::ostream, this must be defined as a non-member.
what's wrong with this code?
class matrix{
private:
friend transpose(const matrix&);
friend class invert;
public: //...
};
matrix (*p)(const matrix&)=&transpose; //error: no transpose() in scope.
what does the statement means "a friend declaration does not introduce a name into enclosing scope".This problem does not occur when friend keyword is removed
The difference between the declaration of transpose() as a friend and without the friend declaration is that if you declare "friend transpose()" all you are doing is telling the compiler that a function friend with the signature shown in the friend declaration can have access to the private members of an object of type matrix. It does not declare a function transpose() with this signature - you still have to do this outside the scope of the matrix class.
If you remove the 'friend' keyword, you are declaring a member function transpose() inside the class matrix, so the compiler actually has seen a function it can take the address of.
ยง7.3.1.2 [namespace.memdef] p3
[...] If a friend declaration in a nonlocal class first declares a class or function the friend class or function is a member of the innermost enclosing namespace. The name of the friend is not found by unqualified lookup or by qualified lookup until a matching declaration is provided in that namespace scope (either before or after the class definition granting friendship). [...]
See also this question of mine.
Friend functions are functions that are not members of a class but
they still have access to the private members of the class.
I should point out that a friend function declaration
may be placed in either the private section or the public section,
but it will be a public function in either case, so it is clearer to
list it in the public section.
class MyClass
{
private:
int data;
public:
MyClass(int value);
friend void myFriend(MyClass *myObject);
};
void myFriend(MyClass *myObject)
{
cout << myObject->data<< endl;
}
MyClass::MyClass(int value)
{
data = value*2;
}
int main()
{
MyClass myObject(3);
myFriend(&myObject);
}
So, you need to define the friend function after you declare it.
G'day!
I have a question around the use of friend in C++. Consider the following piece of code:
#include <ostream>
struct F {
};
struct N {
friend std::ostream& operator<< (std::ostream&, const N&);
friend std::ostream& operator<< (std::ostream&, const F&);
};
void foo(std::ostream &out) {
F bar;
out << bar;
}
My understanding always was, that friend is similar to static with the additional property that the friend function has access to the private part of the class. Under that assumption, the code should compile, since there is an operator<< that takes an ostream& and a (const) F&.
It appears that g++ 4.0 shares my thoughts on this, as it accepts that code. The much newer g++ 4.5(.2) however, rejects the code with the message:
ns.cc: In function 'void foo(std::ostream&)':
ns.cc:14:10: error: no match for 'operator<<' in 'out << bar'
is g++ 4.5 wrong or am I (and g++ 4.0) wrong?
(The solution to move the friend declaration into the F class doesn't help, as the operator<< will need access to the private part of N.)
Regards,
Stefan
The problem is that a friend declaration doesn't provide a global function declaration, unless you provide an inline implementation.
struct N {
friend void func1() { }
friend void func2();
friend void func3();
};
void func3();
func1(); /* OK */
func2(); /* not OK */
func3(); /* OK */
You have to declare the operators outside the struct as well. Same error is reported by gcc 4.4.
#include <ostream>
struct F {
};
struct N {
friend std::ostream& operator<< (std::ostream&, const N&);
friend std::ostream& operator<< (std::ostream&, const F&);
};
std::ostream& operator<< (std::ostream&, const N&);
std::ostream& operator<< (std::ostream&, const F&);
void foo(std::ostream &out) {
F bar;
out << bar;
}
I've been trudging through the standard (FCD, n3242) since I saw the question
In [class.friend] one can read:
6) A function can be defined in a friend declaration of a class if and only if the class is a non-local class (9.8), the function name is unqualified, and the function has namespace scope.
7) Such a function is implicitly inline. A friend function defined in a class is in the (lexical) scope of the class in which it is defined. A friend function defined outside the class is not (3.4.1).
9) A name nominated by a friend declaration shall be accessible in the scope of the class containing the friend declaration.
So, what happens here ?
struct F {
};
struct N {
friend std::ostream& operator<< (std::ostream&, const F&);
};
The friend declaration nominates this overload of operator<< to be a friend of N. However this overload has not been declared in a lexical scope (either namespace or class). Also, 7 does not apply because it is not defined within N either.
Therefore, when looking up the overloads of operator<< that can apply in:
void foo(std::ostream &out) {
F bar;
out << bar;
}
There is no valid overload (actually, it could be there is no overload at all).
You have two solutions:
use 7: define the function inline following the friend declaration.
use 9: declare the function in the namespace too
Because of 4 though:
4) A function first declared in a friend declaration has external linkage (3.5). Otherwise, the function retains its previous linkage (7.1.1).
I would recommend declaring it prior to the friend declaration to control its linkage, but it will rarely matters.