Reputation: 164129
Let's say I want class A to have a variable and a function that are available to all instances but only to them.
I have two ways of doing that (or are there more?):
Have them as private static members:
class A {
...
private:
static int myInt;
static void myMethod();
...
};
Simply have them in the cpp file:
// h file
class A {
...
};
// cpp file
static int myInt;
static void myFunction() { ... }
Both options will do just fine as I see it, but other than design related arguments, what are the differences?
Is any option better than the other?
Are there any performance or optimization issues?
Thanks.
Seems like I was not clear enough, so here's a better example (leaving the old one so that the previous comments/answers will make sense):
First option:
// h file
class A {
public:
A();
~A();
void doSomething();
private:
static std::queue queue;
static boost::mutex mutex;
static void initQueue();
};
// cpp file
// let's assume this method can be called multiple times but only initiates the queue on the first call
void A::initQueue() {
boost::unique_lock<boost::mutex> lock(A::mutex);
...
}
void A::A() {
A::initQueue();
}
void A::doSomething() {
// have full access to the A::queue/A::mutex
}
Second option:
// h file
class A {
public:
A();
~A();
void doSomething();
};
// cpp file
static std::queue queue;
static boost::mutex mutex;
static void initQueue() {
boost::unique_lock<boost::mutex> lock(Amutex);
...
}
void A::A() {
initQueue();
}
void A::doSomething() {
// have full access to the queue/mutex
}
As for the visibility, all I mean is that by including A.h I don't have access to the variables/functions, but only from within class A.
I don't mean how to guard them against malicious code or something.
Upvotes: 1
Views: 171
Reputation: 136218
Private members are an implementation detail which users of a class cannot access. Exposing them in header files creates unnecessary compilation dependencies. For example, private members may require including other header files which slow down compilation of translation units which include the header; changing an implementation detail in the header file requires recompiling all its users. Therefore, it is considered good practice to only expose in header files what users can directly use (the public API) and to avoid exposing implementation details in public API headers as much as possible.
Herb Sutter gives this subject a thorough treatment in GotW #100: Compilation Firewalls.
You can easily move all your non-public static class members into a .cc file and into an unnamed namespace.
Non-static data members can be moved into Pimpl or hidden behind an abstract interface. Pimpl advantage is that it does not require the user to deal with smart-pointers and factories directly and does not use virtual calls which can be slightly slower than non-virtual calls.
Run-time cost of hiding data members implementation is that the implementation of the member functions will have to be in the .cc
so that the calls to your class API cannot be inlined without link-time code generation.
Upvotes: 3
Reputation: 69864
The difference is that the private static members are part of the class, and therefore have access to private and protected members of instances of the class. The free functions would not.
Example:
class A {
A(a) : _a(a) {}
private:
// legal - _a is accessible because get_a is part of A
static int get_a(const A& a) { return a._a; }
private:
int _a;
};
// illegal - _a is a private member of A
static get_a(const A& a) {
return a._a;
}
EDIT in response to OP's edit.
Both implementations are valid.
Upvotes: 0