I have a set of functions that work on a file. Originally I made it into a class, with the only private member being a static const std::string
which was the name of the file. The user used these functions by creating an object and calling functions from it. However, I think I'm going to switch to using a namespace, since it's just a set of functions and makes more sense. The only problem is that I still would like to keep that constant string. Would doing something along these lines be fine?
namespace FileHandler {
// Functions to do stuff with file
const std::string FILE_NAME;
}
I have a separate implementation file for the namespace, but I'm wondering if the loss of encapsulation from having the file name be a private member in a class is worth using the namespace instead.
You can do similar things but they will have different semantics.
In a class, a static variable is a declaration, not a definition, it still requires a definition outside of the class; a variable declaration in a namespace is a definition unless you mark in as extern
and don't provide an initializer.
In your case it doesn't make too much difference as const
variables have internal linkage by default so you can have multiple definitions in a program (one per translation unit) without problems.
E.g.
class Test
{
static const std::string FILE_NAME;
};
is (in some ways) equivalent to:
namespace Test
{
extern const std::string FILE_NAME;
}
If you did this, you would be declaring FILE_NAME
as an empty string. You couldn't redeclare it elsewhere in the same translation unit.
namespace Test
{
const std::string FILE_NAME;
}
You could, though, do this.
namespace Test
{
const std::string FILE_NAME = "myfile.txt";
}
Each translation unit would have its own version of Test::FILE_NAME
but they would all be consistent.
I do not see the problem that led you to switch from using a class to using a namespace. If every function is acting on the file whose name is stored in FILE_NAME
, then the file seems like a perfectly valid part of an object's state. Switching from that to what amounts to a global variable is a strong code smell. What happens when you want to perform operations on two files at once? What if you want to support different file types? It is much easier to address these questions with an object-oriented approach that avoids global state.
If you really want to switch to using "a set of functions", then you may want to consider a more functional approach in which each function takes the name of the file (or a file pointer) as a parameter. That way, the functions have no need to access global state.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With