BG> You know that in good OOP you should avoid global
BG> data/functions. I try to do that as often as possible,
BG> but sometimes I use static data or functions within a class.
BG> What I want to know is, is this as evil as using global data/functions?
You'll probably get widely varying opinions on this, however, no matter what,
I think that you should keep in mind a few things:
a) they're opinions.
b) if you're getting paid, you're getting paid to make it work.
When evaluating an OO design (not that I've had that much experience), I
generally ask simple questions.
1. Does it make sense?
2. Does the language chosen (C++, Java, Smalltalk, Ada, whatever) allow the
construct?
In the case of functions, I ask, on a case by case basis, more questions:
3. Does this function need to be overridden in derived classes (virtual)?
4. If no to #3, does this function require access to read the current state
or to change the current state (which implies access to read) of the object,
or is it merely a helper (private static) or does it just make sense (#1) to
be with this type (public static)?
Examples in #4...
In one object, I needed to make basically the same calculation to two
different variables. I wrote a private static function that took a reference
to the variable to be changed plus other parameters. It could have been
non-static, but since it is private, there's little difference. I assume
that there _could_ be some optimizations with static, so I allow the compiler
to know information that could help it do these optimizations. (There's also
one fewer parameter being passed in static functions - 'this' isn't passed.)
Another object I wanted to guarantee that all allocations were done on the
heap, so I wrote a Construct function that returned a pointer to the object.
Rather than polluting the namespace with this function, I made it static.
This also gave it the added bonus of being able to access the private
constructor:
class foo
{
private:
foo(...);
public:
static foo* Construct(...)
{
return new foo(...);
}
// ...
};
One reason for this could be to put all created foo's in a special heap to
keep track of how many foos are in use. Or into shared memory (special new
here), or ... a miriad of reasons.
And the last example, very similar results to the last, is to put a function
that really belongs in a library, but doesn't need the 'this' pointer. I
know I've used this idea before, but I can't recall the circumstances
offhand. The idea being that you've got a class that does a lot of stuff,
and this function fits in well with that class, so it goes together, but
isn't necessarily a function 'on' an object of that type. Oh, here's an
example:
class File
{
//...
bool delete();
static bool delete(char* filename);
};
You don't need to instantiate a File object to delete the file here. Two
choices here - either the static version can instantiate the File object for
you and call delete, or the non-static can call the static, whichever is
easiest. However this isn't always the case - you may not have a non-static
version of a static function, I just can't remember the circumstance, as I
said.
Now, another question arose with static data. Public static data is the same
thing as a standard global variable. Private static data is basically, IMO,
the same as a static variable in a function. I generally will only put
static variables (privately, of course) in a class when one or more of its
inline functions use it, otherwise it will be a "global" (static,
non-exposed) variable in the implementation file of that class.
i.e.:
class foo
{
static int num_instantiated;
foo() { ++num_instantiated; }
~foo() { --num_instantiated; }
};
In foo.cc:
int foo::num_instantiated;
However, if nothing inline uses it, I'll make it static to foo.cc rather than
class foo instead.
Hope this gives you one way of looking at it...
---
---------------
* Origin: Tanktalus' Tower BBS (1:250/102)
|