c++: Difference between member and non member functions - c++

What is the difference between member and non-member functions in C++?

There are several differences between a member function (which I will now call method) and a free function (which I will now call function).
First, let's just state that they are not so different. Object code can generally be compiled down to C (or assembly) which are procedural languages with no notion of methods. Both methods and functions are then called like subroutines.
Now that this is out of the way, let's look at the differences. They can be classified in two categories: conceptual and syntactic.
Syntactically
The syntax is the obvious part of any language, so it's the easiest to get out of the way.
First note: there are two different kinds of methods in C++ (and a number of other languages), the static methods and regular methods.
Both kinds of methods have full access to the class internals (protected and private sections) as well (of course) as access to the class public interface.
static methods are equivalent to friend functions (apart from some scoping differences).
Within a regular method, a special keyword (this in C++) allows access to the current object on which the method has been invoked (via the ., ->, .* or ->* operators).
A regular method may be const and/or volatile qualified, enabling it for (respectively) const and/or volatile qualified objects. For example, a non-const method cannot be called on a const object. This can be seen as qualifying this within the method, ie void Foo::bar() const has a this of type Foo const*.
A regular method may be marked as virtual. Virtuality enables runtime polymorphism by enabling overriding. I won't extend on this mechanism here, let's just note that functions cannot be virtual.
One often ignored point, is that methods (both static and regular) are scoped within the class. This is important for name lookup (of other methods or attributes/variables) as it means that the elements of the class have priority during lookup from a method on the elements declared outside of the class.
Since the qualification using this-> before attribute or methods is not mandatory, this comes handy in regular methods, though it may introduce subtle bugs. In static methods, it avoids qualifying by the class name the static attributes and methods one whishes to access.
Now that the main syntactic differences have been asserted, let's check the conceptual differences.
Conceptually
OOP is generally about tying together state and behavior (of this state). This is done by creating classes which group attributes (state) and behavior (methods) and (in theory) stating that only the methods can act on the state. Therefore, in OOP, the methods are responsible for implementing the behavior of the class.
The methods participate to the encapsulation of state (freeing clients from the implementation detail) and to the preservation of the class invariants (statements about the class state that hold true from its birth to its death, whatever you do with it).
C++
In C++, as we have seen previously, this is done by using different access levels (public, protected and private) and granting access to the non-public levels to a restricted portion of the code. Generally attributes will be private and thus only accessible to the class methods (and maybe some friends, for syntax quirks).
Note: I urge you not to use protected attributes, it's hard to track down their modifications and since the set of derived classes is unbounded... their implementation cannot be changed easily afterward.
However, beware that C++ discourages from bloating the interface with lots of methods.
The trouble is that because methods are responsible of maintaining invariants, the more there are and the more the responsability is spread, making it more difficult to track down bugs and ensure correctness. Also, since methods depends on the class internals, it makes change more costly.
Instead, in C++, it is generally advised to write a minimal set of methods and delegating the rest of the behavior to non-friend functions (as long as it doesn't increase the cost too much).
See Sutter's take on std::string in Monolith Unstrung.
The delegation to non-friend methods was emphasized by Sutter in its Interface Principle in which he states that functions that are delivered with the class (in the same file/same namespace) and use the class, are logically part of the class interface. He restates in Exceptional C++.
This answer is becoming rather long-winded, yet I suspect that I have overlooked differences that other would find critical... oh well.

A (non-static) member function has an implicit this argument, a non-member doesn't.
Syntactically, you pass that implicit argument on the left of the . or -> operator like.so() or like->so(), instead of as a function argument so( like ).
Likewise, when declaring a member function, you need to do so in the class of which it is a member:
class Class {
public:
void a_public_member_function();
};
Non-member functions are instead declared outside any class (C++ calls this "at namespace scope").
(Non-static) member functions can also be virtual, but non-member functions (and static member functions) cannot.

A non-static member function is invoked on objects of the class it belongs to. It has implicitly access to the this pointer representing the current object. Through this pointer, it may access other members easily and with full access privileges (i.e. access private members).
A non-member function has no implicit this. In the sample below, bar is a member function while freebar is not. Both do more or less the same, but note how bar gets an implicit object pointer via this (also only bar has privileged access to foo's members, freebar only has access to public members).
class foo {
public:
void bar() {
this->x = 0; // equivalent to x = 0;
}
int x;
};
void freebar(foo* thefoo) {
thefoo->x = 1;
}
// ...
foo f;
f.bar();
// f.x is now 0
freebar(&f);
// f.x is now 1
Semantically a member function is more than just a function with an implicit this parameter. It is meant to define the behaviour of an object (i.e. a car object would have drive(), stop() as member functions).
Note that there are also static member functions which have full privileges but don't get an implicit this nor are they invoked through an instance of the class (but rather through the full name of the class).

In the following code, f() is a member function of class Sample, and g() is a non-member function:
class Sample
{
void f();
};
void g();
Its very simple. Since f() is a member of the class Sample, so its called member function (of class Sample). And since g() is not member of any class, so its called non-member function.

A member function is invoked on an object and has access to the fields of the class.
Member functions can be polymorphic (via the virtual keyword) which is essential for OOP.

Member functions get called on instances and have a this pointer available; non-members don't.

Related

Member function vs friend functions: why one and not the other?

Why are functions of objects generally defined as class member functions instead of friend functions (with the associated instantiated object passed in as a parameter)?
If you implement push_back(vector v, val), front(vector v), back(vector) as friend functions that take as a parameter a vector, for example, would that not save on space, because the functions would not have to be defined each time a vector object is created, but only once?
I'm sorry if my question doesn't make much sense. I'm new to coding and I am not completely comfortable with its jargon/terminology. If I need to reword my question because it is unclear, please let me know.
Thank you :)
Unless they’re virtual, member functions don’t take up any space inside a class. And virtual member functions only take up constant space. This is usually 8 bytes, independent of how many virtual functions the class has. This is because classes with virtual functions contain a pointer to a vtable which looks up the actual function at runtime.
That being said, having friend functions at namespace scope is useful because it allows you to make overload sets. An overload set is just the name for all the overloads of a particular function name. For example, std::to_string is an overload set because there are multiple functions with that name.
Overload sets are a really useful concept because they allow you to write generic code that can act on a lot of different types, even if those types are completely unrelated For example, std::vector and std::list don’t inherit from each other or from a base class, but it’s easy to write templated functions that work on either of them because they share a common interface in terms of how they can be used.
If you implement push_back(vector v, val), front(vector v), back(vector) as friend functions that take as a parameter a vector, for example, would that not save on space, because the functions would not have to be defined each time a vector object is created, but only once?
Functions are not "defined each time a vector object is created". You don't save space by using friend functions as such.
The advantages of member functions mostly revolve around inheritance. Member functions can have protected access, and they can be virtual etc.
Friend functions are useful in implementing symmetric binary (i.e. two-argument, counting this) functions. As a member function the first argument would be special and cannot be treated equally. Furthermore, friend functions can provide an API compatible with C, which is useful for cross-language programming and shared libraries.

Why don't methods of structs have to be declared in C++?

Take, for example, the following code:
#include <iostream>
#include <string>
int main()
{
print("Hello!");
}
void print(std::string s) {
std::cout << s << std::endl;
}
When trying to build this, I get the following:
program.cpp: In function ‘int main()’:
program.cpp:6:16: error: ‘print’ was not declared in this scope
Which makes sense.
So why can I conduct a similar concept in a struct, but not get yelled at for it?
struct Snake {
...
Snake() {
...
addBlock(Block(...));
}
void addBlock(Block block) {
...
}
void update() {
...
}
} snake1;
Not only do I not get warnings, but the program actually compiles! Without error! Is this just the nature of structs? What's happening here? Clearly addBlock(Block) was called before the method was ever declared.
A struct in C++ is actually a class definition where all its content is public, unless specified otherwise by including a protected: or private: declaration.
When the compiler sees a class or struct, it first digests all its declarations from inside the block ({}) before operating on them.
In the regular method case, the compiler hasn't yet seen the type declared.
C++ standard 3.4.1:
.4:
A name used in global scope, outside of any function, class or
user-declared namespace, shall be declared before its use in global
scope.
This is why global variables and functions cannot be used before an afore declaration.
.5:
A name used in a user-declared namespace outside of the definition of
any function or class shall be declared before its use in that
namespace or before its use in a namespace enclosing its namespace.
same thing just written again as the .4 paragraph explictely restricted its saying to "global", this paragraph now says "by the way, its true as well in namespeces folks..."
.7:
A name used in the definition of a class X outside of a member
function body or nested class definition29 shall be declared in one of
the following ways: — before its use in class X or be a member of a
base class of X (10.2), or — if X is a nested class of class Y (9.7),
before the definition of X in Y, or shall be a member of a base class
of Y (this lookup applies in turn to Y ’s enclosing classes, starting
with the innermost enclosing class),30 or — if X is a local class
(9.8) or is a nested class of a local class, before the definition of
class X in a block enclosing the definition of class X, or — if X is a
member of namespace N, or is a nested class of a class that is a
member of N, or is a local class or a nested class within a local
class of a function that is a member of N, before the definition of
class X in namespace N or in one of N ’s enclosing namespaces.
I think this speaks of all the code that does not stand in cpu executed code (eg declarative code).
and finally the interesting part:
3.3.7 Class scope [basic.scope.class]
1 The following rules describe the scope of names declared in classes.
1) The potential scope of a
name declared in a class consists not only of the declarative region
following the name’s point of declaration, but also of all function
bodies, brace-or-equal-initializers of non-static data members, and
default arguments in that class (including such things in nested
classes).
2) A name N used in a class S shall refer to the same
declaration in its context and when re-evaluated in the completed
scope of S. No diagnostic is required for a violation of this rule.
3)
If reordering member declarations in a class yields an alternate valid
program under (1) and (2), the program is ill-formed, no diagnostic is
required.
particularly, by the last point they use a negative manner to define that "any ordering is possible" because if re-ordering would change lookup then there is a problem. its a negative way of saying "you can reorder anything and its ok, it doesnt change anything".
effectively saying, in a class, the declaration is looked-up in a two-phase compilation fashion.
"why can I conduct a similar concept in a struct, but not get yelled at for it?"
In a struct or class definition you're presenting the public interface to a class and it's much easier to understand, search and maintain/update that API if it's presented in:
a predictable order, with
minimal clutter.
For predictable order, people have their own styles and there's a bit of "art" involved, but for example I use each access specifier at most once and always public before protected before private, then within those I normally put typedefs, const data, constructors, destructors, mutating/non-const functions, const functions, statics, friends....
To minimise clutter, if a function is defined in the class, it might as well be without a prior declaration. Having both tends only to obfuscate the interface.
This is different from functions that aren't members of a class - where people who like top-down programming do use function declarations and hide the definitions later in the file - in that:
people who prefer a bottom-up programming style won't appreciate being forced to either have separate declarations in classes or abandon the oft-conflicting practice of grouping by access specifier
Classes are statistically more likely to have many very short functions, largely because they provide encapsulation and wrap a lot of trivial data member accesses or provide operator overloading, casting operators, implicit constructors and other convenience features that aren't relevant to non-OO, non-member functions. That makes a constant forced separation of declarations and definitions more painful for many classes (not so much in the public interfaces where definitions might be in a separate file, but definitely for e.g. classes in anonymous namespaces supporting the current translation unit).
Best practice is for classes not to cram in a wildly extensive interface... you generally want a functional core and then some discretionary convenience functions, after which it's worth considering what can be added as non-member functions. The std::string is an often claimed to have too many member functions, though I personally think it's quite reasonable. Still, this also differs from a header file declaring a library interface, where exhaustive functionality can be expected to be crammed together making a separation of even inline implementation more desirable.

static functions compiler optimization C++

I know that we should declare a function as static in a class if its a utility function or if we have to use in a singleton class to access private static member.
But apart from that does a static function provide any sort of compiler optimization too since it doesn't pass the "this" pointer? Why not just use the utility function through an already instantiated object of class? Or is it just a best practice to make utility functions as statics?
Thanks in advance.
The "non-passing-this" optimization can probably be done by the compiler once you turn the optimizations on. As I see it, a static function has rather idiomatic uses:
Implementing modules. There is a bit of overlap here with namespaces, and I would rather use namespaces.
Factories: you can make the constructor protected/private and then have several static functions (with different, explicit names) creating instances.
For function pointers: static functions do not require the slightly more complicated syntax of pointer to member function. That can be a plus when interacting with libraries written for C.
To keep yourself from using this and have the compiler to enforce it. It makes sense sometimes. For example, if you have a commutative operation that takes two instances, a static function that takes the two instances would emphasize (in my opinion) that the operation is commutative. Of course in many cases you would rather overload an operator.
In general a static function will ease namespace and "friend" clutter by prefixing an otherwise ordinary function with the name of a class, presumably because both are tightly related.
Static exists to associate a method with a class, rather than either:
Associating it with an instance of that class (like writing a normal, non-static member function).
Keeping it in the global namespace or whatever namespace you would otherwise be in (like declaring a function just in the file, not in a class).
Static says that 'conceptually this is something tied to/associated with this class, but it does not depend on any instance of that class'.
In more formal terms: a static member function is the same as a function declared outside of a class in all ways other than that it is part of that class's namespace and in that it has access rights to that class's private/protected data members.
Going back to your question:
There is no optimization gain here.
Utility function has nothing to do with it. It's whether or not it makes sense to scope the function in the class itself (rather than an instance of it).
It does not 'pass the this pointer' because there is no instance to speak of. You can call a static member function without ever invoking that class's constructor.

C++ : friends of class and "this" pointer

I have one little question for you :), I understand that every method "secretly" gets "this" pointer of some class that they are inside but why that wont happen to "friend" functions ?
Is it because they are NOT methods of class?
Can anyone explain whole machinery, i am very interested in how "this" really works!
thanks in advance! :)
friend functions and classes are just used for access control checked by the compiler.
friend functions are just standard functions, so there won't be any differences regarding calling conventions.
friend functions are not member of any class, so no this pointer is passed (as done with static member functions)
Non-static member function of a class will get a hidden this pointer (depending on the ABI this is often the first argument), static member functions don't get the this pointer because they don't act on instance data.
How exactly the this pointer is passed to a member function heavily depends on the used ABI, which depends on the architecture and operating system. Either it will be pushed on the stack, or it will be passed through a well known register.
Please consider reading "Where is the 'this' pointer stored in computer memory?".
"Friendship" and "Membership" are two different things. A function can be a member function or not, and independantly be a friend function or not.
You can declare a member function to be a friend function of another class, i.e.
class B{
friend void A::func(B);
//stuff
};
Here, the member function func from class A is declared as friend and can access B's private, and it will have a this pointer, that points to the object of class A on which func has been called.
The this pointer is an implicit parameter of non-static member functions, which is described in section 9.3.2 of the C++ Standard. How it is passed to the function depends on your compiler/architecture, i.e. it is implementation defined (so you might want to read your favorite compiler's documentation to learn about how it manages this pointers).

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.