Is there a good reason why should a class function member be part of the class if it does not depend on any of the members of the class?
No. In fact, you should prefer free-functions over member functions. Only functions that really need to operate on the members should be member functions, the rest should use them to provide functionality.
Assuming you mean "does not depend on any non-public members", Scott Meyers once answered a definite no to that question.
However, he focused only on encapsulation: encapsulation is improved by making those functions non-members.
Other considerations can, for example, include that you cannot call operator<< on a temporary if the operator is defined as a non-member. (Why would you ever want to do that? Well, for example to build up a string argument from constituent parts, iostream-style.)
And the considerations can include simply how natural and clear the usage notation is. The notation with nested calls (as for non-members) can be rather annoying and unclear. That's why we have -> as syntactic sugar for * dereferencing + member selection.
So, if you focus only on encapsulation, then move those member functions out of class, as Scott Meyers adviced. And otherwise, make an engineering decision where aspects such as usability and notational clarity are also considered. Anyway, don't fret about it: it's probably not incredibly important. :-)
Cheers & hth.,
If its correlated with the meaning of the class, you should put it together even if it do not use any member of the Class.
The reason it for simply the development, and for a future developer know where to look.
It often happens when overriding a virtual function. If the base class has a pure virtual along the lines of getWidgetCount(), for example, and your derived class doesn't support widgets, it would just return 0.
the most common case concern utility classes for example if i have to develop functions to convert BSTR to string and vice versa , i can create a class with static methods.
it's useful to package functions concerning the same area in the same class, another solution is to package them in the same namespace, but unfortunatly namespaces are not very used even in the well known c++ librairies.
and for other cases adding method to a class with no relation with other members increase the lack of cohesion and the metric LCOM will be high, and the design will be impacted.
Related
Does C++20 offer any new solutions to the problem of public member invisibility and source code bloat/repetition with inherited class templates described in this question over 2 years ago ?
The "Problem"
The alleged "problem" is that, in a template, an unqualified name used in a way which isn't dependent on the specialization is truly independent of the specialization and refers to the entity with that name found at that point. The alleged source code "bloat" is using this-> to explicitly make the name dependent or qualifying the name. This is still the situation in C++20.
Just to be clear, the set of entities is not known at the point we refer to them. In the linked question, the base class depends on the template parameter, and we have only seen the primary base class template. The base class template may be specialized later and may have completely different member functions than the ones we've seen. So, any "solution" requires that a name without any obvious contextual dependence on the specialization find entities not yet declared which may be surprising.
Why It's Impossible
Any naive changes in this direction are either pretty big or have severe downsides, or both.
You could postpone all name lookup until instantiation time, discarding two phase lookup. That invites ODR violations which is silent UB, which is a huge downside.
You could restrict specialization so that you cannot specialize the base class later such that a different entity is found. That is difficult to diagnose, so it would likely be a new rule introducing silent UB.
You could opt in with a using declaration: using X::* as you propose or using class X as someone else suggested in a different context. This has the benefit of explicitness. It moves the problem a level up: if X is not dependent, presumably it should be found now, but if it is dependent, what happens? We can't instantiate it prior to instantiating the template we're in now. Thus, we can't interpret any names we see until instantiation. It has similar downsides to discarding two phase lookup.
Any of these changes would add complexity to an already complex area and would also pose significant backwards compatibility hurdles. None of them is a clear win.
Note: In C++20 they did make the rules more uniform by allowing ADL to find function templates with specified parameters to be found: f<int>(1).
Why It's Not a Problem
I doubt there would be consensus that this really is a problem. The linked question makes a poor argument. The derived class adds member function behavior to a certain base class, but a free function works better. These behaviors did not need member access, they aren't required by the language to be members, they can be found as non-members with ADL, and by using a free function they apply even when the static type you have is the base type. So, using inheritance for this is unnecessary coupling, and is a worse option.
Searching for 100s of places to add this-> and adding these 6 characters 100s of times strikes me as Code Bloat and Repetition when I have to templatize a base class
"Searching": The compiler will tell you when a name can't be found, which is better than silent bad behavior, such as making ODR violations easier to hit.
"templatize a base": Templatizing the base class doesn't trigger this. Templatizing the derived class and making the base dependent does. Yes, when templatizing the derived class, specifying that a bare name used in a way that is independent of the template parameter is in fact dependent may seem like boilerplate to some, but others might argue being explicit is clearer.
"100s of times": Seems hyperbolic.
These code patterns are used all the time in real world. Just look at CRTP. (comment on linked question)
Again, this only applies if the derived class is templated. I would dispute the commonality, but these idioms do exist and have a place.
Most importantly, though, is that CRTP is not a goal. CRTP is a hack. It's a C++ idiom because C++ lacks better facilities. CRTP allows a class to opt into certain behaviors that would otherwise be bothersome to write. Relevant C++ proposals do exist, but by and large, they have focused on making extension easier or removing boilerplate, and not on making CRTP, the hack, easier.
These are some that come to mind:
C++20: Comparisons
A very common use of CRTP is for things that require a lot of extra boilerplate. C++ required you to define operator== and operator!=, for instance. By opting into a CRTP base class, one could define only the primitive operation and have the other one generated.
C++20 fixed the underlying problem with comparisons. The typical member-wise comparison can be defaulted, and comparisons can be re-written so that != can invoke ==.
The problem is solved at the root, removing CRTP, not enhancing it.
C++20: Iterators to Ranges
Another common use of CRTP in the same vein as above is iterators. Writing custom iterators requires only a few fundamental operations: advance and dereference for forward iterators. But then there's a lot of extra seemingly unnecessary ceremony: pre-increment, post-increment, const iterators, typedefs, etc.
C++20 took a large step forward by introducing range concepts and the range library. The result is that it should be much less necessary to write a custom iterator. Ranges become a capable concept on their own, and there's a good suite of range combinators.
C++20: Concepts
C++ essentially has two systems for specifying an interface: virtual functions and concepts. They have trade-offs. Virtual functions are intrusive. But prior to C++20, concepts were implicit and emulated. One reason to use CRTP or inheritance generally would be to inject virtual functions. But in C++20, concepts are a language feature removing one big negative.
Future C++: Metaclasses
One value of CRTP in addition to the boilerplate reduction is satisfying an entire collection of multiple type requirements. A comparable class defines all the comparison operators. An clonable base defines a virtual destructor and clone.
This is the topic of metaclasses, which is not yet in C++.
See Also
See also the work on customization points which seems very interesting. And see the debates on unified function call syntax, which seems like we'll never get.
Summary
There's a very good question hiding in here about how C++20 makes it easier to reduce boilerplate, remove hacks like CRTP, and write better and clearer code. C++20 takes several steps in this regard, but they made the expression of intent easier, not a particular idiom.
My question title pretty much asks it all. I've recently found out that it is good programming practice in C++ to pass many values by const reference and mark certain methods in classes as a constant method. Right now, I have a library that I have been writing for myself for a while now that has absolutely no const-correctness, so I'd like to start rectifying that little by little.
In what specific scenarios should I make a method constant? So far I know "getter" methods should generally be made constant (since the code in one shouldn't modify any class variables), but do I do that for all methods that are considered getters, or only specific ones? And outside of getter methods, what other scenarios should methods be made constant?
but do I do that for all methods that are considered getters, or only specific ones?
You should do that for all methods that don't modify the non-mutable members. They include not only getter functions but also any overloaded operator functions, such as operator==, operator!=, operator<.
When should I make a method constant?
As a rule of the thumb, you should make a method constant whenever none of the object's member variables are altered.
As an additional guideline, you should do this only when you are sure the method will not be altered in the future to change member variables.
Ultimately, if you are planning to make a method affect member variables, it should be non-constant. Otherwise, it should be constant.
Why are those C++11 new functions of header <string> (stod, stof, stoull) not member functions of the string class ?
Isn't more C++ compliant to write mystring.stod(...) rather than stod(mystring,...)?
It is a surprise to many, but C++ is not an Object-Oriented language (unlike Java or C#).
C++ is a multi-paradigm language, and therefore tries to use the best tool for the job whenever possible. In this instance, a free-function is the right tool.
Guideline: Prefer non-member non-friend functions to member functions (from Efficient C++, Item 23)
Reason: a member function or friend function has access to the class internals whereas a non-member non-friend function does not; therefore using a non-member non-friend function increases encapsulation.
Exception: when a member function or friend function provides a significant advantage (such as performance), then it is worth considering despite the extra coupling. For example even though std::find works really well, associative containers such as std::set provide a member-function std::set::find which works in O(log N) instead of O(N).
The fundamental reason is that they don't belong there. They
don't really have anything to do with strings. Stop and think
about it. User defined types should follow the same rules as
built-in types, so every time you defined a new user type,
you'd have to add a function to std::string. This would
actually be possible in C++: if std::string had a member
function template to, without a generic implementation, you
could add a specialization for each type, and call
str.to<double>() or str.to<MyType>(). But is this really
what you want. It doesn't seem like a clean solution to me,
having everyone writing a new class having to add
a specialization to std::string. Putting these sort of things
in the string class bastardizes it, and is really the opposite
of what OO tries to achieve.
If you were to insist on pure OO, they would have to be
members of double, int, etc. (A constructor, really. This
is what Python does, for example.) C++ doesn't insist on pure
OO, and doesn't allow basic types like double and int to
have members or special constructors. So free functions are
both an acceptable solution, and the only clean solution
possible in the context of the language.
FWIW: conversions to/from textual representation is always
a delicate problem: if I do it in the target type, then I've
introduced a dependency on the various sources and sinks of text
in the target type---and these can vary in time. If I do it in
the source or sink type, I make them dependent on the the type
being converted, which is even worse. The C++ solution is to
define a protocol (in std::streambuf), where the user writes
a new free function (operator<< and operator>>) to handle
the conversions, and counts on operator overload resolution to
find the correct function. The advantage of the free function
solution is that the conversions are part of neither the data
type (which thus doesn't have to know of sources and sinks) nor
the source or sink type (which thus doesn't have to know about
user defined data types). It seems like the best solution to
me. And functions like stod are just convenience functions,
which make one particularly frequent use easier to write.
Actually they are some utility functions and they don't need to be inside the main class. Similar utility functions such as atoi, atof are defined (but for char*) inside stdlib.h and they too are standalone functions.
For some time I've been designing my class interfaces to be minimal, preferring namespace-wrapped non-member functions over member functions. Essentially following Scott Meyer's advice in the article How Non-Member Functions Improve Encapsulation.
I've been doing this with good effect in a few small scale projects, but I'm wondering how well it works on a larger scale. Are there any large, well regarded open-source C++ projects that I can take a look at and perhaps reference where this advice is strongly followed?
Update: Thanks for all the input, but I'm not really interested in opinion so much as finding out how well it works in practice on a larger scale. Nick's answer is closest in this regard, but I'd like to be able to see the code. Any sort of detailed description of practical experiences (positives, negatives, practical considerations, etc) would be acceptable as well.
I do this quite a bit on the project I work on; the largest of which at my current company is around 2M lines, but it's not open source, so I can't provide it as a reference. However, I will say that I agree with the advice, generally speaking. The more you can separate the functionality which is not strictly contained to just one object from that object, the better your design will be.
By way of an example, consider the classic polymorphism example: a Shape base class with subclasses, and a virtual Draw() function. In the real world, Draw() would need to take some drawing context, and potentially be aware of the state of other things being drawn, or the application in general. Once you put all that into each subclass implementation of Draw(), you're likely to have some code overlap, or most of your actual Draw() logic will be in the base class, or somewhere else. Then consider that if you want to re-use some of that code, you'll need to provide more entry points into the interface, and possibly pollute the functions with other code not related to drawing shapes (eg: multi-shape drawing correlation logic). Before long, it'll be a mess, and you'll wish you had a draw function which took a Shape (and context, and other data) instead, and Shape just had functions/data which were entirely encapsulated and not using or referencing external objects.
Anyway, that's my experience/advice, for what it's worth.
I'd argue that the benefit of non-member functions increases as the size of the project increases. The standard library containers, iterators, and algorithms library are proof of this.
If you can decouple algorithms from data structures (or, to phrase it another way, if you can decouple what you do with objects from how their internal state is manipulated), you can decrease coupling between your classes and take greater advantage of generic code.
Scott Meyers isn't the only author who has argued in favor of this principle; Herb Sutter has too, especially in Monoliths Unstrung, which ends with the guideline:
Where possible, prefer writing functions as nonmember nonfriends.
I think one of the best examples of an unneccessary member function from that article is std::basic_string::find; there is no reason for it to exist, really, as std::find provides exactly the same functionality.
OpenCV library does this. They have a cv::Mat class that presents a 3D matrix (or images). Then they have all the other functions in the cv namespace.
OpenCV library is huge and is widely regarded in its field.
One practical advantage of writing functions as nonmember nonfriends is that doing so can significantly reduce the time it takes to thoroughly test and verify the code.
Consider, for example, the sequence container member functions insert and push_back. There are at least two approaches to implementing push_back:
It can simply call insert (it's behavior is defined in terms of insert anyway)
It can do all the work that insert would do (possibly calling private helper functions) without actually calling insert
Obviously, when implementing a sequence container, you probably want to use the first approach. push_back is just a special form of insert and (to the best of my knowledge) you can't really get any performance benefit by implementing push_back some other way (at least not for list, deque, or vector).
However, to thoroughly test such a container, you have to test push_back separately: since push_back is a member function, it can modify any and all of the internal state of the container. From a testing standpoint, you should (must?) assume that push_back is implemented using the second approach because it is possible that it could be implemented using the second approach. There is no guarantee that it is implemented in terms of insert.
If push_back is implemented as a nonmember nonfriend, it can't touch any of the internal state of the container; it must use the first approach. When you write tests for it, you know that it can't break the internal state of the container (assuming the actual container member functions are implemented correctly). You can use that knowledge to significantly reduce the number of tests that you need to write to fully exercise the code.
(I don't have time to write this up nicely, the following's a 5 minute brain dump which doubtless can be ripped apart at various trival levels, but please address the concepts and general thrust.)
I have considerable sympathy for the position taken by Jonathan Grynspan, but want to say a bit more about it than can reasonably be done in comments.
First - a "well said" to Alf Steinbach, who chipped in with "It's only over-simplified caricatures of their viewpoints that might seem to be in conflict. For what it's worth I don't agree with Scott Meyers on this matter; as I see it he's over-generalizing here, or he was."
Scott, Herb etc. were making these points when few people understood the trade-offs or alternatives, and they did so with disproportionate strength. Some nagging hassles people had during evolution of code were analysed and a new design approach addressing those issues was rationally derived. Let's return to the question of whether there were downsides later, but first - worth saying that the pain in question was typically small and infrequent: non-member functions are just one small aspect of designing reusable code, and in enterprise scale systems I've worked on simply writing the same kind of code you'd have put into a member function as a non-member is rarely enough to make the non-members reusable. It's pretty rare for them to even express algorithms that are both complex enough to be worth reusing and yet not tightly bound to the specific of the class they were designed for, that being weird enough that it's practically inconceivable some other class will happen along supporting the same operations and semantics. Often, you also need to template arguments, or introduce a base class to abstract the set of operations required. Both have significant implications in terms of performance, being inline vs out-of-line, client-code recompilation.
That said, there's often less code changes and impact study required when changing implementation if operations have been implementing in terms of a public interface, and being a non-friend non-member systematically enforces that. Occasionally though, it makes the initial implementation more verbose or in some other way less desirable and maintainble.
But, as a litmus test - how many of these non-member functions sit in the same header as the only class for which they're currently applicable? How many want to abstract their arguments via templates (which means inlining, compilation dependencies) or base classes (virtual function overheads) to allow reuse? Both discourage people from seeing them as reusable, but when not the case, the operations available on a class are delocalised, which can frustrate developers perception of a system: the develop often has to work out for themselves the rather disappointing fact that - "oh - that will only work for class X".
Bottom line: most member functions aren't potentially reusable. Much corporate code isn't broken into clean algorithm versus data with potential for reuse of the former. That kind of division just isn't required or useful or conceivably useful 20 years down the road. It's much the same as get/set methods - they're needed at certain API boundaries, but can constitute needless verbosity when ownership and use of the code is localised.
Personally, I don't have an all or nothing approach to this, but decide what to make a member function or non-member based on whether there's any likely benefit to either, potential reusability versus locality of interface.
I also do this alot, where it seems to make sense, and it causes absolutely no problems with scaling. (although my current project is only 40000 LOC) In fact, I think it makes the code more scalable - it slims down classes, reduces dependencies.
It sometimes requires you to refactor your functions to make them independent of members of the class - and thereby often creating a library of more general helper functions, which you can easly reuse elsewhere. I'd also mention that one of the common problems with many large projects is the bloating of classes - and I think preferring non-member, non-friend functions also helps here.
Prefer non-member non-friend functions for encapsulation UNLESS you want implicit conversions to work for class templates non-member functions (in which case you better make them friend functions):
That is, if you have a class template type<T>:
template<class T>
struct type {
void friend foo(type<T> a) {}
};
and a type implicitly convertible to type<T>, e.g.:
template<class T>
struct convertible_to_type {
operator type<T>() { }
};
The following works as expected:
auto t = convertible_to_type<int>{};
foo(t); // t is converted to type<int>
However, if you make foo a non-friend function:
template<class T>
void foo(type<T> a) {}
then the following doesn't work:
auto t = convertible_to_type<int>{};
foo(t); // FAILS: cannot deduce type T for type
Since you cannot deduce T then the function foo is removed from the overload resolution set, that is: no function is found, which means that the implicit conversion does not trigger.
I've just been browsing and spotted the following...
When should you use a class vs a struct in C++?
The consensus there is that, by convention, you should only use struct for POD, no methods, etc.
I've always felt that some types were naturally structs rather than classes, yet could still have a few helper functions as members. The struct should still be POD by most of the usual rules - in particular it must be safe to copy using memcpy. It must have all member data public. But it still makes sense to me to have helper functions as members. I wouldn't even necessarily object to a private method, though I don't recall ever doing this myself. And although it breaks the normal POD rules, I wouldn't object to a struct having constructors, provided they were just initialise-a-few-fields constructors (overriding assignment or destructors would definitely be against the rules).
To me a struct is intuitively a collection of fields - a data structure node or whatever - whereas a class is an abstraction. The logical place to put the helper functions for your collection-of-fields may well be within the struct.
I even think I once read some advice along these lines, though I don't remember where.
Is this against accepted best practice?
EDIT - POD (Plain Old Data) is misrepresented by this question. In particular, a struct can be non-POD purely because a member is non-POD - e.g. an aggregate with a member of type std::string. That aggregate must not be copied with memcpy. In case of confusion, see here.
For what it's worth, all the standard STL functors are defined as structs, and their sole purpose is to have member functions; STL functors aren't supposed to have state.
EDIT: Personally, I use struct whenever a class has all public members. It matters little, so long as one is consistent.
As far as the language is concerned, it doesn't matter, except for default private vs. public access. The choice is subjective.
I'd personally say use struct for PODs, but remember that "POD" doesn't mean "no member functions". It means no virtual functions, constructors, destructor, or operator=.
Edit: I also use structs for simple public-access aggregates of data, even if their members aren't PODs.
I tend to use struct a lot.
For the "traditional" OOP classes (the ones that represent a specific "thing"), I tend to use class simply because it's a common convention.
But most of my classes aren't really OOP objects. They tend to be functors, and traits classes and all sorts of other more abstract code concepts, things I use to express myself, rather than modelling specific "things". And those I usually make struct. It saves me having to type the initial public:, and so it makes the class definition shorter and easier to get an overview of.
I also lean towards making larger, more complex classes class. Except this rarely affects anything, because I lean even more towards refactoring large, complex classes... And then I'm left with small simple ones, which might be made struct's.
But in either case, I'd never consider it "evil". "Evil" is when you do something that actively obfuscates your code, or when you make something far more complex than necessary.
But every C++ programmer knows that struct and class mean virtually the same thing. You're not going to be confused for long because you see a struct Animal {...}; You know that it's a class designed to model an animal. So no, it's not "evil" no matter which way you do it.
When I have control over the style guides, everything is defined as a struct. Historically, I wanted all my objects to be one or the other, since I was taught it was undefined behavior to forward declared a struct as a class, and vice versa (I'm not sure if this was ever actually true, its just what I was told). And really, struct has the more reasonable default state.
I still do the same because I've never been convinced of the value of using it as a form of documentation. If you need to convey that an object only has public members, or doesn't have any member functions, or whatever arbitrary line you chose to draw between the two, you have actual documentation available for that. Since you never actually use the struct or class keyword when using the type, you would need to go hunting for the definition anyhow if you want the information. And with everybody having their own opinion on what struct actually means, its usefulness as self-documentation is reduced. So I shoot for consistency: everything as one or the other. In this case, struct.
Its not a popular way of doing things, to say the least. Fortunately for everybody involved, I very rarely have control over the coding standards.
I use a struct whenever I need an aggregate of public data members (as opposed to class, which I use for types that come with a certain level of abstractions and have their data private).
Whether or not such a data aggregate has member functions doesn't matter to me. In fact, I rarely ever write a struct without also providing at least one constructor for it.
You said, "To me a struct is intuitively a collection of fields - a data structure node or whatever". What you are describing is Plain Old Data. The C++ standard does have an opinion of what POD means with respect to C++ language features. I suggest that, where possible, you adopt the meaning of POD used in C++0x.
I need to find a reference for this, but I thought that, as far as type definitions are concerned, the keywords "struct" and "class" are to be synonyms in C++0x. The only difference being that class defaults to private members, while a struct defaults to public. This means that you'll never see complier error messages like "Type X first seen using struct, now seen using class." once we're all using C++0x.
I think that it is wrong to have strict rules on when to use class and when to use struct. If consistency is important to you, the go ahead and make a coding standard that has what ever sort of rules you like. Just make sure everyone knows that your coding standard relates to how you want you code to look - it doesn't relate to the underlying language features at all.
Maybe to give an example where I break all your rules, you say "To me a struct is intuitively a collection of fields - a data structure node or whatever - whereas a class is an abstraction." When I want to write a class that implements some abstraction, I define the interface as a struct with pure virtual methods (egad!) - this is exposed in a header, as too is a factory method to construct my concrete class. The concrete class is not exposed i a public header at all. Since the concrete class is a secret, it can be implemented however I like and it makes no difference to external code.
I'd suggest that if you think that the keywords struct and class have any relation to the concept of POD, then you're not understanding C++ yet.