My question refers to:
Using a lambda expression versus a private method
Now that lambda functors are part of C++, they could be used to unclutter a class' interface. How does lambda use vs private method use compare in C++? Do there exist better alternatives to unclutter class interfaces?
Although lambdas can definitely replace some private member functions, thinking of them as means to uncluttering the interface of a class is taking too narrow a view of both lambdas and private member functions.
Private member functions (and functions in general) are the basic units of code reuse. They let you write a piece of logic once, and then hide it behind the name of the function.
Although lambdas can replace a private member function in certain context, they could replace an object of which that function is a member along with it, which is a whole lot more. Due to lambda's ability to capture the context around them, you get a way of creating code blocks that take not only your object with it, but also the state of your local variables. Before lambdas you needed to create a special class for that; lambdas let you create such classes on the fly, for much better readability.
Do there exist better alternatives to unclutter class interfaces?
A method I use quite often is to provide a series of functions with file-scope in an unnamed namespace that act as "helpers" to my member functions.
For example:
// Foobar.cpp
#include "Foobar.h"
namespace {
void someHelper()
{
std::cout << "I'm a helper!" << std::endl;
}
}
void Foobar::someMemberFunc()
{
someHelper();
[...]
}
You can, of course, also declare lambdas and/or classes in this unnamed namespace as well. Anything declared in this unnamed namespace will only be accessible from within the same translation unit (eg, cpp file).
Lambda is a way to move logic into the flow of your code. The only purpose is improving readability, and they can help or they can hurt
If a private/lambda is short, it is often easier for a reader to comprehend it on the spot, rather than having to remember to look at a different function later.
If a private/lambda is long, and appears incongruous with the code calling it, this can distract the reader from a greater pattern in the code. Imagine if you were reading one of these StackOverflow answers and suddenly had to stop to read StackEnglish's description of null and void to make sense of the answer. You'd really rather just see a hyperlink of "optional information" than a copy/paste of the contents.
It is far easier to construct a lambda which holds onto upvalue arguments than it is to construct a private functor to do the same. This can increase readability due to lambdas having less boilerplate in accomplishing that goal.
lambdas are harder to share between sections of code. If you find yourself calling the same function from many places, private functions may be a better match.
How does lambda use vs private method use compare in C++
One may capture the this pointer, therefore having access to a class's internals without cluttering its interface. Previously, under certain circumstances one would require either a member or a friend function (use in conjunction with bind and mem_fn) in stl algorithms.
Added, one should strive to keep interfaces minimal, as changing them is more costly. For this reason idioms like pimpl are popular, and for the same reason a lambda may be preferred over a member function. As mentioned by another person, one should consider that functions are also tools of reuse, but in that case I would prefer a pimpl with private functions, which negates reuse of lambdas for this purpose.
It has a matter of personal taste in it if you ask me, the difference between the two is not huge.
Lambdas are really good for stl algorithms, while private methods, are not as comftorable for that, on the other hand, i find private methods much better if you want to reuse your code.
This question shows the best usages of lambdas imo : lambdas
Personally, i prefer private methods, espessialy in the case you presented. Lambdas should not be used instead of private methods. It clutters the function's body and diverts the eye from the main logic.
Although it unclutter the class, it clutters the function, which i find worse.
Related
This question title is taken from the title of item #23 in Effective C++ 3rd Edition by Scott Meyers. He uses the following code:
class WebBrowser {
public:
void clearCache();
void clearHistory();
void removeCookies();
//This is the function in question.
void clearEverything();
};
//Alternative non-member implementation of clearEverything() member function.
void clearBrowser(WebBrowser& wb) {
wb.clearCache();
wb.clearHistory();
wb.removeCookies();
};
While stating that the alternative non-member non-friend function below is better for encapsulation than the member function clearEverything(). I guess part of the idea is that there are less ways to access the internal member data for the WebBrowser if there are less member functions providing access.
If you were to accept this and make functions of this kind external, non-friend functions, where would you put them? The functions are still fairly tightly coupled to the class, but they will no longer be part of the class. Is it good practice to put them in the class's same CPP file, in another file in the library, or what?
I come from a C# background primarily, and I've never shed that yearning for everything to be part of a class, so this bewilders me a little (silly though that may sound).
Usually, you would put them in the associated namespace. This serves (somewhat) the same function as extension methods in C#.
The thing is that in C#, if you want to make some static functions, they have to be in a class, which is ridiculous because there's no OO going on at all- e.g., the Math class. In C++ you can just use the right tool for this job- a namespace.
So clearEverything is a convenience method that isn't strictly necessary. But It's up to you to decide if it's appropriate.
The philosophy here is that class definitions should be kept as minimal as possible and only provide one way to accomplish something. That reduces the complexity of your unit testing, the difficulty involved in swapping out the whole class for an alternate implementation, and the number of functions that could need to be overridden by sub-classes.
In general, you shouldn't have public member functions that only invoke a sequence of other public member functions. If you do, it could mean either: 1) you're public interface is too detailed/fine-grained or otherwise inappropriate and the functions being called should be made private, or 2) that function should really be external to class.
Car analogy: The horn is often used in conjunction w/ slamming on your brakes, but it would be silly to add a new pedal/button for that purpose of doing both at once. Combining Car.brake() and Car.honk() is a function performed by Driver. However, if a Car.leftHeadLampOn() and Car.rightHeadLampOn() were two separate public methods, it could be an example of excessively fine grained control and the designer should rethink giving Driver a single Car.lightsOn() switch.
In the browser example, I tend to agree with Scott Meyers that it should not be a member function. However, it could also be inappropriate to put it in the browser namespace. Perhaps it's better to make it a member of the thing controlling Web browser, e.g. part of a GUI event handler. MVC experts feel free to take over from here.
I do this a lot. I've always put them into the same .cpp as the other class member functions. I don't think there is any binary size overhead depending where you put them though. (unless you put it in a header :P)
If you want to go down this route the imlementation of clearEverything should be put in both the header (declaration) and implementation of the class - as they are tightly coupled and seems the best place to put them.
However I would be inclined to place them as a part of the class - as in the future you may have other things to clear or there may be a better or faster implementation to implement clearEverythingsuch as droppping a database an just recreate the tables
Over time I have come to appreciate the mindset of many small functions ,and I really do like it a lot, but I'm having a hard time losing my shyness to apply it to classes, especially ones with more than a handful of nonpublic member variables.
Every additional helper function clutters up the interface, since often the code is class specific and I can't just use some generic piece of code.
(To my limited knowledge, anyway, still a beginner, don't know every library out there, etc.)
So in extreme cases, I usually create a helper class which becomes the friend of the class that needs to be operated on, so it has access to all the nonpublic guts.
An alternative are free functions that need parameters, but even though premature optimization is evil, and I haven't actually profiled or disassembled it...
I still DREAD the mere thought of passing all the stuff I need sometimes, even just as reference, even though that should be a simple address per argument.
Is all this a matter of preference, or is there a widely used way of dealing with that kind of stuff?
I know that trying to force stuff into patterns is a kind of anti pattern, but I am concerned about code sharing and standards, and I want to get stuff at least fairly non painful for other people to read.
So, how do you guys deal with that?
Edit:
Some examples that motivated me to ask this question:
About the free functions:
DeadMG was confused about making free functions work...without arguments.
My issue with those functions is that unlike member functions, free functions only know about data, if you give it to them, unless global variables and the like are used.
Sometimes, however, I have a huge, complicated procedure I want to break down for readability and understandings sake, but there are so many different variables which get used all over the place that passing all the data to free functions, which are agnostic to every bit of member data, looks simply nightmarish.
Click for an example
That is a snippet of a function that converts data into a format that my mesh class accepts.
It would take all of those parameter to refactor this into a "finalizeMesh" function, for example.
At this point it's a part of a huge computer mesh data function, and bits of dimension info and sizes and scaling info is used all over the place, interwoven.
That's what I mean with "free functions need too many parameters sometimes".
I think it shows bad style, and not necessarily a symptom of being irrational per se, I hope :P.
I'll try to clear things up more along the way, if necessary.
Every additional helper function clutters up the interface
A private helper function doesn't.
I usually create a helper class which becomes the friend of the class that needs to be operated on
Don't do this unless it's absolutely unavoidable. You might want to break up your class's data into smaller nested classes (or plain old structs), then pass those around between methods.
I still DREAD the mere thought of passing all the stuff I need sometimes, even just as reference
That's not premature optimization, that's a perfectly acceptable way of preventing/reducing cognitive load. You don't want functions taking more than three parameters. If there are more then three, consider packaging your data in a struct or class.
I sometimes have the same problems as you have described: increasingly large classes that need too many helper functions to be accessed in a civilized manner.
When this occurs I try to seperate the class in multiple smaller classes if that is possible and convenient.
Scott Meyers states in Effective C++ that friend classes or functions is mostly not the best option, since the client code might do anything with the object.
Maybe you can try nested classes, that deal with the internals of your object. Another option are helper functions that use the public interface of your class and put the into a namespace related to your class.
Another way to keep your classes free of cruft is to use the pimpl idiom. Hide your private implementation behind a pointer to a class that actually implements whatever it is that you're doing, and then expose a limited subset of features to whoever is the consumer of your class.
// Your public API in foo.h (note: only foo.cpp should #include foo_impl.h)
class Foo {
public:
bool func(int i) { return impl_->func(i); }
private:
FooImpl* impl_;
};
There are many ways to implement this. The Boost pimpl template in the Vault is pretty good. Using smart pointers is another useful way of handling this, too.
http://www.boost.org/doc/libs/1_46_1/libs/smart_ptr/sp_techniques.html#pimpl
An alternative are free functions that
need parameters, but even though
premature optimization is evil, and I
haven't actually profiled or
disassembled it... I still DREAD the
mere thought of passing all the stuff
I need sometimes, even just as
reference, even though that should be
a simple address per argument.
So, let me get this entirely straight. You haven't profiled or disassembled. But somehow, you intend on ... making functions work ... without arguments? How, exactly, do you propose to program without using function arguments? Member functions are no more or less efficient than free functions.
More importantly, you come up with lots of logical reasons why you know you're wrong. I think the problem here is in your head, which possibly stems from you being completely irrational, and nothing that any answer from any of us can help you with.
Generic algorithms that take parameters are the basis of modern object orientated programming- that's the entire point of both templates and inheritance.
I've found myself that I tend not to have private class functions. If possible, all candidates to private class function rather I put in to unnamed namespace and pass all necessary information as function parameters. I don't have a sound explanation why I'm doing that but at least it looks more naturally to me. As a consequence I need to expose less internal details in the header file.
What is your opinion - is it correct practice?
In the semi large projects where I usually work (more than 2 million lines of code) I would ban private class functions if I could. The reason being that a private class function is private but yet it's visible in the header file. This means if I change the signature (or the comment) in anyway I'm rewarded sometimes with a full recompile which costs several minutes (or hours depending on the project).
Just say no to that and hide what's private in the cpp file.
If I would start fresh on a large c++ project I would enforce PIMPL Idiom: http://c2.com/cgi/wiki?PimplIdiom to move even more private details into the cpp file.
I've done this in the past, and it has always ended badly. You cannot pass class objects to the functions, as they need to access the private members, presumably by reference (or you end up with convoluted parameter lists) so you cannot call public class methods. And you can't call virtual functions, for the same reason. I strongly believe (based on experience) that this is A Bad Idea.
Bottom line: This sounds like the kind of idea that might work where the implementation "module" has some special access to the class, but this is not the case in C++.
It basically comes down to a question of whether the function in question really makes sense as part of the class. If your only intent is to keep details of the class out of the header, I'd consider using the pimpl idiom instead.
I think this is a good practice. It often has the benefit of hiding auxiallary structures and data types as well, which reduces the frequency and size of rebuilds. It also makes the functions easier to split out into another module if it turns out that they're useful elsewhere.
So, I have a class. It's a useful class. I like a lot. Let's call it MyUsefulClass.
MyUsefulClass has a public method. Let's call it processUsefulData(std::vector<int>&).
Now suppose processUsefulData really does two things and I want to refactor it from this:
std::vector<int> MyUsefulClass::processUsefulData(std::vector<int>& data)
{
for (/*...*/)
{
for (/*...*/)
{
// a bunch of statements...
}
}
for (/*...*/)
{
for (/*...*/)
{
// a bunch of other statements...
}
}
return data;
}
Now, I want to split these responsibilities and rewrite the code as
std::vector<int> MyUsefulClass::processUsefulData(std::vector<int>& data)
{
doProcessA(data, dataMember_);
doProcessB(data, otherDataMember_);
return data;
}
So, I don't know if I should make the two helper functions free functions or member functions, and when each would be appropriate. I also don't know if it's better to make them in an anonymous namespace or not. Does anyone know good times to do this?
I generally make helper routines "free" routines in an anonomous namespace if possible. That way I don't complicate the interface (off in the *.h file) with stuff clients don't need to worry about.
However, you have to be careful that you don't introduce non-reentrancy by doing that. For instance, by modifying global data objects or static locals rather than class members. If you need to do that, you are better off making it a proper class member.
Free function / member function
I would make them free functions is possible (they do not need access to the internals of the class). If they work on a set of attributes or need access to other members then make it a member function.
Access
If the code only has sense in this scope, and will not be used from other code then make them private: private if it is a member, or implemented in an unnamed namespace if it is a free function.
If other code will benefit from using the code then publish it in the interface. That means making it protected if it is a member or having the free function accessible through a header in a named namespace (or global namespace).
I usually make them protected or private member functions. It would depend on whether you plan on deriving the class and overriding the functions.
If they are common enough functions that they are used in other classes, move them to static functions contained in a common class or a separate object that your class uses.
Always prefer free functions over member ones.
See my answer here to know why.
The fact that you mention free functions leads me to believe that the 'bunch of other statements' do not require access to class data. If so, make them free. This reduces complexity of your class header, plus free functions are easier to use in the standard algorithms (maybe std::for_each since you're working with vectors anyway?).
Think about the scope. Are those functions going to be used in another class, or elsewhere? Should they be publically call-able?
It seems like they should be private member functions to me, but it all depends on your overall scoping structure.
Member functions certainly if the original function made sense as a member function.
Private/protected IMHO depends on how their functionality is used: if the original function's operation is still required and the refactor is solely to make the code cleaner then make them protected or private and call them from the regular function. You get the refactor but keep the class's public interface intact that way.
In the (otherwise) excellent book C++ Coding Standards, Item 44, titled "Prefer writing nonmember nonfriend functions", Sutter and Alexandrescu recommend that only functions that really need access to the members of a class be themselves members of that class. All other operations which can be written by using only member functions should not be part of the class. They should be nonmembers and nonfriends. The arguments are that:
It promotes encapsulation, because there is less code that needs access to the internals of a class.
It makes writing function templates easier, because you don't have to guess each time whether some function is a member or not.
It keeps the class small, which in turn makes it easier to test and maintain.
Although I see the value in these argument, I see a huge drawback: my IDE can't help me find these functions! Whenever I have an object of some kind, and I want to see what operations are available on it, I can't just type "pMysteriousObject->" and get a list of member functions anymore.
Keeping a clean design is in the end about making your programming life easier. But this would actually make mine much harder.
So I'm wondering if it's really worth the trouble. How do you deal with that?
Scott Meyers has a similar opinion to Sutter, see here.
He also clearly states the following:
"Based on his work with various string-like classes, Jack Reeves has observed that some functions just don't "feel" right when made non-members, even if they could be non-friend non-members. The "best" interface for a class can be found only by balancing many competing concerns, of which the degree of encapsulation is but one."
If a function would be something that "just makes sense" to be a member function, make it one. Likewise, if it isn't really part of the main interface, and "just makes sense" to be a non-member, do that.
One note is that with overloaded versions of eg operator==(), the syntax stays the same. So in this case you have no reason not to make it a non-member non-friend floating function declared in the same place as the class, unless it really needs access to private members (in my experience it rarely will). And even then you can define operator!=() a non-member and in terms of operator==().
I don't think it would be wrong to say that between them, Sutter, Alexandrescu, and Meyers have done more for the quality of C++ than anybody else.
One simple question they ask is:
If a utility function has two independent classes as parameteres, which class should "own" the member function?
Another issue, is you can only add member functions where the class in question is under your control. Any helper functions that you write for std::string will have to be non-members since you cannot re-open the class definition.
For both of these examples, your IDE will provide incomplete information, and you will have to use the "old fashion way".
Given that the most influential C++ experts in the world consider that non-member functions with a class parameter are part of the classes interface, this is more of an issue with your IDE rather than the coding style.
Your IDE will likely change in a release or two, and you may even be able to get them to add this feature. If you change your coding style to suit todays IDE you may well find that you have bigger problems in the future with unextendable/unmaintainable code.
I'm going to have to disagree with Sutter and Alexandrescu on this one. I think if the behavior of function foo() falls within the realm of class Bar's responsibilities, then foo() should be part of bar().
The fact that foo() doesn't need direct access to Bar's member data doesn't mean it isn't conceptually part of Bar. It can also mean that the code is well factored. It's not uncommon to have member functions which perform all their behavior via other member functions, and I don't see why it should be.
I fully agree that peripherally-related functions should not be part of the class, but if something is core to the class responsibilities, there's no reason it shouldn't be a member, regardless of whether it is directly mucking around with the member data.
As for these specific points:
It promotes encapsulation, because there is less code that needs access to the internals of a class.
Indeed, the fewer functions that directly access the internals, the better. That means that having member functions do as much as possible via other member functions is a good thing. Splitting well-factored functions out of the class just leaves you with a half-class, that requires a bunch of external functions to be useful. Pulling well-factored functions away from their classes also seems to discourage the writing of well-factored functions.
It makes writing function templates easier, because you don't have to guess each time whether some function is a member or not.
I don't understand this at all. If you pull a bunch of functions out of classes, you've thrust more responsibility onto function templates. They are forced to assume that even less functionality is provided by their class template arguments, unless we are going to assume that most functions pulled from their classes is going to be converted into a template (ugh).
It keeps the class small, which in turn makes it easier to test and maintain.
Um, sure. It also creates a lot of additional, external functions to test and maintain. I fail to see the value in this.
It's true that external functions should not be part of the interface. In theory, your class should only contain the data and expose the interface for what it is intended and not utilitarian functions. Adding utility functions to the interface just grow the class code base and make it less maintainable. I currently maintain a class with around 50 public methods, that's just insane.
Now, in reality, I agree that this is not easy to enforce. It's often easier to just add another method to your class, even more if you are using an IDE that can really simply add a new method to an existing class.
In order to keep my classes simple and still be able to centralize external function, I often use utility class that works with my class, or even namespaces.
I start by creating the class that will wrap my data and expose the simplest possible interface. I then create a new class for every task I have to do with the class.
Example: create a class Point, then add a class PointDrawer to draw it to a bitmap, PointSerializer to save it, etc.
If you give them a common prefix, then maybe your IDE will help if you type
::prefix
or
namespace::prefix
In many OOP languages non-friend non-class methods are third-class citizens that reside in an orphanage unconnected to anything. When I write a method, I like to pick good parents - a fitting class - where they have the best chances to feel welcome and help.
I would have thought the IDE was actually helping you out.
The IDE is hiding the protected functions from the list because they are not available to the public just as the designer of the class intended.
If you had been within the scope of the class and typed this-> then the protected functions would be displayed in the list.