Encapsulating related utility functions

M

Marco

One of the things I like about C++ is that it doesn't force you to
create fake "objects" in the OO sense. We had a debate at the office
about the "right" way to encapsulate related utility functions (such
as additional math functions). These would be pure functions with no
state.

1) Create a class with all static functions

2) Use a named namespace

Please site articles or books if possible.
 
E

Erik Wikström

One of the things I like about C++ is that it doesn't force you to
create fake "objects" in the OO sense. We had a debate at the office
about the "right" way to encapsulate related utility functions (such
as additional math functions). These would be pure functions with no
state.

1) Create a class with all static functions

2) Use a named namespace

Please site articles or books if possible.

Ask your self this (or ask your collogues):

* If you will never instantiate it why use a class, or put another way:
how is it object-oriented to create a class but never create any
objects from it?

* If you create a class with static functions, what relation does these
functions have with the class (except that the class provides a
namespace for the functions)?
 
J

Juha Nieminen

Marco said:
One of the things I like about C++ is that it doesn't force you to
create fake "objects" in the OO sense. We had a debate at the office
about the "right" way to encapsulate related utility functions (such
as additional math functions). These would be pure functions with no
state.

1) Create a class with all static functions

2) Use a named namespace

One advantage of namespaces and consequently a disadvantage of classes
is that the contents of a namespace don't have to be declared all in one
place, which is the case with classes.

This is quite handy when creating large libraries. If the library is
extensive, containing many types and functions, you might want to put
all of it inside a common namespace, which is specific to that library,
in order to avoid garbaging the global namespace. Since the library is
very large, it's obviously a good idea to split it into several header
files, each containing one logical module. The great thing about
namespaces is that you can still put everything into a common namespace
even though the declarations have been split into several headers. You
just can't do this with classes (well, at least not in C++ anyways).

(It's precisely the property of namespaces that they cannot be
"instantiated" that allows this.)

Naturally the 'using' keyword also allows interesting possibilities
(such as "importing" one namespace into another), but IMO that's secondary.
 
K

Kai-Uwe Bux

Erik said:
Ask your self this (or ask your collogues):

* If you will never instantiate it why use a class, or put another way:
how is it object-oriented to create a class but never create any
objects from it?

And what's wrong with it not being OO?

* If you create a class with static functions, what relation does these
functions have with the class (except that the class provides a
namespace for the functions)?

In the case of the OP, probably none; but then again: why would that be bad?

One difference between a class and a namespace is that you (or anybody else)
can add stuff to a namespace whereas a class is closed.

A more interesting difference is that a class can be used as a template type
parameter. That can make option (1) appropriate in some cases. The class
can provide implementations (and sometimes even semantics) for primitive
operations used in an algorithm. (E.g., one could have a string class that
takes a policy class supplying implementations of search and pattern
matching algorithms; or you could have a vector whose reallocation strategy
is governed by a policy. Changing the policy would be a way to optimize a
program.)


Now, to evaluate the options (1) and (2) on their merits, I still agree that
if those template tricks don't enter the picture, option (2) is the way to
go. But that is simply because I don't see why you would want to close the
namespace.



Best

Kai-Uwe Bux
 
J

James Kanze

On 2008-06-22 16:22, Marco wrote:
Ask your self this (or ask your collogues):
* If you will never instantiate it why use a class, or put another way:
how is it object-oriented to create a class but never create any
objects from it?

To close it? A class differs from a namespace in several ways.
One, of course, is that you can't instantiate a namespace.
Another is that you can't add names to a class. Yet a third is
that a class can have private members.

Obviously (I think), none of these issues apply to additional
math functions, and these should probably be in a namespace.
But there are probably cases where closure or private members
are an issue, in which case, a class should be used.
* If you create a class with static functions, what relation
does these functions have with the class (except that the
class provides a namespace for the functions)?

If the functions are private, they can only be called by other
members of the class.

Note that I'm just playing the devil's advocate here. Generally
speaking, the original question can be restated to ask "is it
appropriate to confuse the reader by pretending something is OO
when you're not?"
 
M

Marcel Müller

Hi!
Ask your self this (or ask your collogues):

* If you will never instantiate it why use a class, or put another way:
how is it object-oriented to create a class but never create any
objects from it?

* If you create a class with static functions, what relation does these
functions have with the class (except that the class provides a
namespace for the functions)?

There are meaningful semantics of classes with only static members.

For example something like that:

template<class T, class K>
class instance_repository
{public:
// abstract factory interface used for object instantiation
struct IFactory
{ virtual T* operator()(K& key) = 0;
};

public:
// Get an existing instance of T or return NULL.
static intrusive_ptr<T> FindByKey(const K&);
// Get an existing instance of T or create a new one.
static intrusive_ptr<T> GetByKey(K& key, IFactory& factory);
private:
static sorted_vector<T*, const K&> Index;
static mutex Mtx; // protect the index above
};


Marcel
 
D

Daniel Pitts

Marco said:
One of the things I like about C++ is that it doesn't force you to
create fake "objects" in the OO sense. We had a debate at the office
about the "right" way to encapsulate related utility functions (such
as additional math functions). These would be pure functions with no
state.

1) Create a class with all static functions

2) Use a named namespace

Please site articles or books if possible.
Use a named namespace. The effect is the same (and the accessing syntax
will likely be the same). The benefit of using a namespace is that
namespaces are open, and you can have several header files which "add"
to the namespace.

For example, say you have functions for trig, and functions for algebra.
It might make sense to put them all in the namespace my_math_space, but
have "trig.h" and "algebra.h". You couldn't do that that a class.

Classes should, in general, be used to encapsulate state/value. If you
have no state or value, then a class doesn't make sense. Note, type is
part of state, so polymorphic classes without data members do make sense
as classes.

Hope this helps,
Daniel.
 
M

Marco

One of the things I like about C++ is that it doesn't force you to
create fake "objects" in the OO sense. We had a debate at the office
about the "right" way to encapsulate related utility functions (such
as additional math functions). These would be pure functions with no
state.

1) Create a class with all static functions

2) Use a named namespace

site

oops that should be: Please cite articles or books if possible.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top