Always create classes in C++? [closed]
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
开发者_JAVA百科 Improve this questionComing 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.
If you find you have a class where every method is static, then perhaps a namespace
would be more appropriate.
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
Free, stateless, side-effect free functions that perform some operations/calculations/transformations on their arguments and return the result(s).
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.
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();
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.
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.
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).
精彩评论