What are the benefits of free functions in an unnamed namespace over a class with private member functions?
Asked Answered
E

3

34

What is the advantage of having a free function (in anonymous namespace and accessible only in a single source file) and sending all variables as parameters as opposed to having a private class member function free of any parameters and accessing member variables directly?

header:

 class A {
    int myVariable;
    void DoSomething() {
       myVariable = 1;
    }
 };

source:

 namespace {
    void DoSomething2(int &a) {
        a = 1;
    }
 }

 int A::SomeFunction() {
    DoSomething2(myVariable); // calling free function
    DoSomething(); // calling member function
 }

If you prefer making them members, then what if I have a case where I first call a function that is not accessing any member variables, but that function calls another function which is accessing a member. Should they both be member functions or free?

Easiness answered 9/1, 2014 at 18:55 Comment(5)
Can you at least write code that tries to compile?Hydromel
@StephaneRolland no, that link is about public interface, not about implementationLibertinage
@Libertinage let me insist, it is about using member functions or not. Let me quote the answer saying: "By having lots and lots of methods depending directly on the internals of the class, the slightest change implies a whole rewrite. It need not be so."Typical
@StephaneRolland your points are well appreciated, but they all refer to interfaces, not implementations. Some of the benefits are the same though, less recompilation.Libertinage
@Libertinage Another benefit may be that a class that has a slightly more little size. But I understand now why you focuss me on the implementation side.Typical
T
31

see this question: Effective C++ Item 23 Prefer non-member non-friend functions to member functions and also C++ Member Functions vs Free Functions

You should prefer free functions, in the extent that it promotes loose coupling.

Consider making it a member function only if it works on the guts of your class, and that you consider it really really tied to your class.

It is a point of the book 101 C++ coding standards, which states to prefer free function and static function over member functions.

Altough this may be considered opinion based, it allows to keep class little, and to seperate concerns.

This answer states: "the reason for this rule is that by using member functions you may rely too much on the internals of a class by accident."

Typical answered 9/1, 2014 at 19:2 Comment(2)
Isn't the problem with member functions that they don't keep state of any variables or pointers inside of it? I mean, when the free function terminate, so do any pointers and variables you have declared in the member function...Kleon
Not sure I understand what you mean. I would correct and repharse your sentence to my understanding this way: there's not many difference between a free function and a method. We could simplify and say that methods simply have access to another input parameter which is called this, and which is implicit passed, and accessible inside the method. A method has ABSOLUTELY no different behaviour than free functions regarding the scope of lives of local variables and pointers.Typical
L
15

One advantage of a non-member function in a source file is similar to the benefits of the Pimpl idiom: clients using your headers do not have to recompile if you change your implementation.

// widget.h
class Widget 
{
public:
    void meh();
private:
    int bla_;
};

// widget.cpp
namespace {
    void helper(Widget* w) // clients will never know about this
    { /* yadayada */ }
}

void widget::meh() 
{ helper(this); }

Of course, when written like this, helper() can only use the public interface of Widget, so you gain little. You can put a friend declaration for helper() inside Widget but at some point you better switch to a full-blown Pimpl solution.

Libertinage answered 9/1, 2014 at 19:3 Comment(0)
F
10

The primary advantage of free functions vs member functions is that it helps decouple the interface from the implementation. For example, std::sort doesn't need to know anything about the underlying container on which it operates, just that it's given access to a container (through iterators) that provide certain characteristics.

In your example the DoSomething2 method doesn't do much to decrease coupling since it still has to access the private member by having it passed by reference. It's almost certainly more obvious to just do the state mutation in the plain DoSomething method instead.

When you can implement a task or algorithm in terms of a class's public interface then that makes it a good candidate to make a free function. Scott Meyers summarizes a reasonable set of rules here: http://cpptips.com/nmemfunc_encap

Forefather answered 10/1, 2014 at 18:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.