17

Coming from a Java background it is new for me to deal with the choice of creating a class or just implementing the functions I might need. Normally this is no question when it comes to modeling something which could have a state.

Now I am implementing a shared library which has no main function and exclusively static member functions. Does something speak against creating a class to encapsulate the functions?

Further I wanted to encapsulate further code, especially auxillary functions, in another file. The execute code is always the same and the state of it does not change, so I guess I would declare them also static - so the same questions arises here to.

Giovanni Funchal
  • 8,934
  • 13
  • 61
  • 110
Konrad Reiche
  • 27,743
  • 15
  • 106
  • 143
  • 2
    Might be interesting: [Static members class vs normal C-like interface](http://stackoverflow.com/questions/4977330/static-members-class-vs-normal-c-like-interface). – Xeo Apr 19 '11 at 19:58

6 Answers6

20

If you find you have a class where every method is static, then perhaps a namespace would be more appropriate.

chrisaycock
  • 36,470
  • 14
  • 88
  • 125
10

Frankly, this is philosophical, and kind of fuzzy guidelines, but I prefer to use the simplest things first then build up in terms of complexity when its needed.

My first preference is

  1. Free, stateless, side-effect free functions that perform some operations/calculations/transformations on their arguments and return the result(s).

  2. However, if any of those arguments evolve to become stateful, and your function become in charge of maintaining that state, consider wrapping stateful data and methods that manipulate that data into a class for good encapsulation/data hiding.

File I/O is an example of something that's stateful. You open a file, write some data to it which moves ahead a write pointer, and ultimately close it, its a good example of where you'd want a class.

The most obvious example of a place where a free functions are best are math. Other examples might be performing a regex, transforming one kind of message into another kind, etc.

(1) Is simplest because in its purest form there's no persistent state, everything is transformational, and you should consistently get the same output with the same input. Easy to test, easy to figure out how it works. Ideally we wouldn't need to persist any state and we could all program this way.

(2) Is needed because safely updating state is a necessary part of life and if you can't do any data hiding or encapsulation you lose confidence that state is being maintained correctly and safely.

Doug T.
  • 64,223
  • 27
  • 138
  • 202
  • 2
    +1 for putting this in terms of "whether or not the function has state is what should make this decision". – Billy ONeal Apr 19 '11 at 20:05
  • +1 Thank you for taking out all the fuss and useless considerations that pollute that kind of discussion about nothing. – gd1 Apr 20 '11 at 00:14
  • @Giacomo yeah its still kind of fuzzy, because you don't want to put every operation that can possibly operate on a stateful piece of data into a method, but those functions should at least work through the stateful object's safe, nicely encapsulated interface to do something. But I think in general, this is still good advice. – Doug T. Apr 20 '11 at 00:16
4

You may want to define a namespace instead of a class.

namespace mycode
{
    //Code for the library here
    void myfunction()
    {
         //function definition
    }
}

then when you need to use it you can either preface it or use the namespace

mycode::myfunction()

or

using mycode;

myfunction();
Kyle Sletten
  • 5,365
  • 2
  • 26
  • 39
3

Actually, if the code does not belong in a class, you should not put it in a class in C++. That is, one should prefer non-friend non-member functions to member and friend functions. The reason is that pulling the method out of the class results in better encapsulation.

But don't take my word for it, see Scott Meyers' Effective C++ Item #23: Prefer non-member non-friend functions to member functions.

Billy ONeal
  • 104,103
  • 58
  • 317
  • 552
  • I would appreciate a comment explaining the downvote. And if it is revenge for me downvoting on another answer, that's a horrible reason to downvote... – Billy ONeal Apr 19 '11 at 20:15
  • +1: I agree this d/v appears unwarranted. Although this isn't the most helpful answer (ie because it doesnt attend to how to decide if code does or does not belong in a class), and is debateable (some would argue that static publics are more natural), it is certainly not incorrect. – John Dibling Apr 19 '11 at 20:20
  • @John, I think three of the most influential personalities in the C++ world (Meyers, Sutter, Alexandrescu) publicly announcing that you should prefer non-member non-friend functions almost always makes for a pretty good argument. – ltjax Apr 19 '11 at 20:24
  • @ltjax: I'm not saying they are wrong, just that it's debatable. Note that I up-voted @Billy's answer. – John Dibling Apr 19 '11 at 20:27
  • @John: I feel I really can't go too much into exactly why I think that way because to do that I'd effectively have to copy Meyers' chapter, and I really don't think that's fair to him. – Billy ONeal Apr 19 '11 at 20:28
  • @ltjax: Hmm.. I actually kind of agree with John here; smart people agreeing with me is not sufficient justification for a course of action. But the book does the explaining I think needs to go here. – Billy ONeal Apr 19 '11 at 20:30
  • +1 for reference to an excellent book ... thinking about what you _should_ do is sometimes more important than what you _could_ do. – AJG85 Apr 19 '11 at 20:31
  • @Billy, yes of course - it's not so much about that about those people as how they argue for that cause and they do that in a very convincing way! (And that is actually works very well - in my experience). Maybe a quote or smth would have been good? – ltjax Apr 19 '11 at 20:53
3

Not sure if I completely understand you but yes you can create a container class that provides static methods. It may be worthwhile to make the constructors private to prevent people from instantiation an instance of the class.

class HelperFunctions
{
public:
    static void DoSomethingUseful() { /* useful bits */ }
    // yata yata
private:
    HelperFunctions(); // private default constructor
    HelperFunctions(const HelperFunctions&); // private copy constructor
};

Then you could do something like this:

HelperFunctions::DoSomethingUseful();

But you couldn't do something like this:

HelperFunctions myHelperFunction; // private constructor = compile error

You also could create namespaces for the purpose of organization non-member functions.

namespace HelperFunctions
{
   void DoSomethingUseful() { /* useful bits */ }
   // yata yata
}

Remember you can define namespaces across multiple files as well making these particular useful for grouping objects and functions wherever they may be. This is preferable as it logically separates the functions making the design and intended use more obvious

Unlike Java where everything is a method in C++ we can have functions at a global, namespace, or member scope. You also can have non-member friend functions which can access internal members of a class without being a member of the class themselves.

Basically you can do whatever you want including shoot yourself in the foot.

Edit: Why so serious?

I wasn't suggesting what the OP should or shouldn't do. It seemed as though they were new to C++ coming from the Java world where everything is a method and all "functions" are class members. To that affect my answer was to show how firstly you can create something in C++ similar to what you might have in Java and secondly how you can do other things as well and why that is.

As others have stated it's considered good practice to prefer non-member non-friend functions when possible for various reasons. I agree if you do not need an object with state than you probably shouldn't design one. However I'm not sure if the OP was looking for a philosophical discussion on best practice in design and implementation or just a curiosity for equivalent C++.

I had hoped my last line joking about shooting yourself in the foot was enough to make the point that "just because you can, doesn't mean you should" but perhaps not with this crowd.

AJG85
  • 15,849
  • 13
  • 42
  • 50
  • 12
    -1: Yes, you *can* do this. But if you construct a class with public statics and even go to the length of making the ctor `private:` so that nobody can instantiate it, then IMO you should just make these non-member functions within a namespace. Putting them within a class gives you nothing aside from a namespace scope (which you can get directly) and might imply semantics that doesn't exist. – John Dibling Apr 19 '11 at 20:24
  • -1 I totally agree with John. – ltjax Apr 19 '11 at 20:25
  • +1 for succinctly pointing out all the places C++ allows us to put functions; though a little more advice as to when someone should use which one would be nice. :) (For the record I agree with John and ltjax, but it's a subjective thing there...) – Billy ONeal Apr 19 '11 at 20:26
  • @John @ltjax: I don't think AJG85 is saying that's the right course of action to take; he's saying that it's *possible* to do it that way (which it is). I agree with you guys but I don't think it's an extremely bad answer. – Billy ONeal Apr 19 '11 at 20:27
  • 2
    @Billy, @AJG85, @platzhirsch: Honestly, if OP hadn't **accepted** this answer, I wouldn't have downvoted it. But OP specifically said "Does something speak against creating a class to encapsulate the functions?" And I think the answer to *that* question is "yes." This indicates to me that OP thinks that this means they *should* be static members, and I'm trying to draw attention to the fact that some (most) of us don't think they should. – John Dibling Apr 19 '11 at 20:31
  • I might be diverging, but I prefer [singletons](http://stackoverflow.com/questions/1008019/c-singleton-design-pattern) to this static-methods-and-private-constructor pattern. Even if it looks stateless now, things always evolve and the singleton pattern accommodates better for evolution in terms of state. – Giovanni Funchal Apr 19 '11 at 20:44
  • 3
    @Giovanni: Please, say it isn't so. – John Dibling Apr 19 '11 at 20:59
  • @Giovanni - singletons are bad! [Why Singletons are Evil](http://blogs.msdn.com/b/scottdensmore/archive/2004/05/25/140827.aspx) – ltjax Apr 19 '11 at 21:00
  • @Giovanni Now the can of worms if fully opened ;) Many believe that singletons are widely overused. Some go as far as to call it an anti-pattern. In this case one could argue it would be worse than the static methods container class as now you have semantics enforcing the existence of only one instance of an object which doesn't need to exist at all. – AJG85 Apr 19 '11 at 21:01
  • 1
    @AJG85: re your edit. When I read OP's "Does something speak against creating a class to encapsulate the functions?" that sounded to me like he was soliciting advice about what he *should or shouldn't do*. You answer wasn't wrong, but when OP accepted it it told me that *he* thought it was what he should do, and *that's* wrong. You just happen to be an innocent victim here. – John Dibling Apr 19 '11 at 21:02
  • I don't think this way. Sure there are implementation issues around singletons, most of them are linked to C++ and not conceptual. Yes, they might be overused by bad developers but they are bad developers and that's all. Singletons feels better for me than the static-methods-and-private-constructor. – Giovanni Funchal Apr 19 '11 at 21:07
  • @John I guess I **should** have said that the second option is what you probably **should** do as part my answer. In general I'm against forceful declarations of "The One Right Way™" but let me go ahead and add that now. – AJG85 Apr 19 '11 at 21:09
  • @Giovanni: some would say that a design should be as simple as possible (but no simpler). Given a situation where you don't need a class, should you: (a) not have a class; (b) have an empty class, but not instantiate it; (c) have an empty class, plus code to prevent instantiation; (d) have an empty class, plus code to force instantiation; or (e) none of the above? – Mike Seymour Apr 19 '11 at 21:12
  • @AJG85: Actually, if OP was going to notice the debate about what he should or should not do, he would have noticed by now. And at this point, d/ving your answer no longer really serves any purpose, so I'll just reverse it. FWIW, I'm also against One True Way declarations. – John Dibling Apr 19 '11 at 21:20
0

Careful, in C++, static functions are functions that are only visible to other functions in the same file. So basically they are auxiliary functions that cannot be part of the interface of a library.

Static methods in classes is something completely different (even though the same keyword is used in both cases). They are just like normal functions that can call protected/private methods in the same class. You can think of static methods as simple (non-static) functions that are "friends" with the class.

As for the general guideline, I don't think it matters if you have (non-static) functions or static methods as the interface of your library, this is mostly a matter of syntax: call f() or call obj::f(). You can also use namespaces for encapsulation. In this case the syntax is: ns::f() for a function and ns::obj::f() for a static method.

EDIT: Ok, I though there was a confusion around the keyword static, turns out this is more of a controversial answer than I would have wanted it to be. I personally prefer the term method for member functions (which is also the same vocabulary used in the actual question). And when I said static methods can call private methods I was referring to visibility (a.k.a. access control).

Giovanni Funchal
  • 8,934
  • 13
  • 61
  • 110
  • @Billy ONeal, did you miss the word "static"? – ergosys Apr 19 '11 at 20:11
  • I am talking about **static functions** as opposed to **static methods**. Also C++ is not a superset of C. See this: http://stackoverflow.com/questions/1201593/c-subset-of-c-where-not-examples – Giovanni Funchal Apr 19 '11 at 20:12
  • -1: Re: "They are just like normal functions that can call protected/private methods in the same class." static methods are very different from normal methods. to wit, you *can not* call a non-static method from a static method, because there is no `this` pointer. – John Dibling Apr 19 '11 at 20:14
  • @ergosys: No, I did not. But I did miss the distinction between "function" and "method". The C++ standard does not use the designation "method" -- it uses the designation "member function" or "nonmember function". I'd remove my downvote if @Giovanni would edit his answer (because right now I cannot change it), and I'll change it to an upvote if he changes it to use the language of the standard. – Billy ONeal Apr 19 '11 at 20:14