[newbie to C++] what is the best way to...

M

mati-006

Hi
I'm writing a client/server application (actually rewriting it from C).
I need three classes, one for connecting and handling this connection
(client class), one for listening (server class) and one handling the
connections for each client (server class).

I have two helper classes
(with not yet determined scope of members (private/public/protected)):

class Address {
unsigned char ip[4]; /**< IP in network byte order */
unsigned char port[2]; /**< port in network byte order */
bool ishostname;
/* this writes resolved address into ip[] and port[] */
void resolve_hostname(char *hostname, int port);
};

class Connection {
Socket socket; /**< The Socket */
bool issocket;
.... /* write,read,close functions..erm, methods ;-) */
};

I have following ideas:

- public inheritance, make methods in helper classes public and data
fields protected (to allow methods in derived classes to access them)
- composition, make methods and data fields in helper classes public,
write "dummy" methods in new classes (in order not to write Y.X.write()
but simply Y.write)
- composition, make only methods in helper classes public, but write
additional methods to access private members, and write "dummy" methods
in new classes too

Which of them (or is there any other?) is The Proper One?
I'm close to use the inheritance, because it is simplest (I think), but
similar problems described in books (I'm learning from Thinking in C++)
are resolved by composition. However, I don't have any idea how to make
it nice and proper using the composition.
 
L

Luke Meyers

mati-006 said:
I have two helper classes
(with not yet determined scope of members (private/public/protected)):

Some will dogmatically insist on making all member data private. I
think this is *usually* the best idea, with a couple of exceptions
(that may or may not apply in your case). First, behaviorless classes
for which the structure basically *is* the interface do not benefit
from trivial encapsulation, so you might as well just make the data
members public. Stepping out a bit farther along the limb, if a class
has some behavior but it is trivial enough (for example, all static
methods, or methods which never assume any invariants wrt member data),
it might be reasonable to make member data public in that case. In
such cases, though, it might make more sense to simply write the
behavior as free functions.

I find protected member data difficult to recommend, generally
speaking. Member data of const reference types (generally bound to
private data) are a reasonable exception, and cleaner than protected
accessors.
class Address {
unsigned char ip[4]; /**< IP in network byte order */
unsigned char port[2]; /**< port in network byte order */
bool ishostname;
/* this writes resolved address into ip[] and port[] */
void resolve_hostname(char *hostname, int port);
};

Don't forget to consider migrating from C idioms to C++ idioms -- for
example, changing naked arrays to std::vector, char* to std::string,
etc.
class Connection {
Socket socket; /**< The Socket */
bool issocket;
... /* write,read,close functions..erm, methods ;-) */
};

"Member functions," please! Methods are for Java and Smalltalk and
such like. ;)
- public inheritance, make methods in helper classes public and data
fields protected (to allow methods in derived classes to access them)
- composition, make methods and data fields in helper classes public,
write "dummy" methods in new classes (in order not to write Y.X.write()
but simply Y.write)
- composition, make only methods in helper classes public, but write
additional methods to access private members, and write "dummy" methods
in new classes too

Which of them (or is there any other?) is The Proper One?
I'm close to use the inheritance, because it is simplest (I think), but
similar problems described in books (I'm learning from Thinking in C++)
are resolved by composition. However, I don't have any idea how to make
it nice and proper using the composition.

A few non-orthogonal rules of thumb:

* Use public inheritance to model the concept of "Derived is USABLE-AS
(usu. IS-A) Base."
* Do not use inheritance simply to re-use behavior.
* Prefer composition to inheritance.
* In most cases where you'd want to use private inheritance,
composition is preferable.
* Prefer forwarding functions (delegation) to accessors (getters).

I'd say go with composition, and just deal with the fact that you have
to write forwarding functions. It seems like unnecessary duplication
at first, but I think the duplication in this case is a reasonable
consequence. It avoids improper public inheritance (you're not IS-A...
not sure about USABLE-AS), and being explicit about your own interface
is generally a good idea. Actually a lot easier in terms of
maintainability, since you don't have to go searching through base
class headers to determine the full extent of your interface, as in the
case of public inheritance.

So, composition, forwarding functions, and consider whether the little
helper classes would work better as just behaviorless structs, maybe
with some free functions (or possibly simple and/or static member
functions to complement them).

Luke

P.S. I haven't read the Thinking in C++ books -- any good? I was
thinking about getting volume 2.
 
M

mati-006

Thanks a lot.
P.S. I haven't read the Thinking in C++ books -- any good? I was
thinking about getting volume 2.

I've found vol 1 pretty useful, because it's just different than any
other book/tutorial/course that I've read, many aspects not covered
elsewhere can be found there, but on the other hand, I have a feeling
that some stuff is omitted.
IMO TICPP + something else is a very good way to learn.

BTW the Thinking in books are available to download from Bruce Eckel's
site, so even if you don't like reading from the screen, you can view
what's inside.

Here is the link:
http://mindview.net/Books/DownloadSites
(I recommend downloading from master site, because mirrors are often
outdated)
 

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,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top