Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fine to have variables in a namespace?

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.

like image 397
Anonymous Avatar asked Feb 27 '23 18:02

Anonymous


2 Answers

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.

like image 190
CB Bailey Avatar answered Mar 08 '23 08:03

CB Bailey


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.

like image 21
Brett Daniel Avatar answered Mar 08 '23 08:03

Brett Daniel