Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Defining many classes in a single file

Reply
Thread Tools

Defining many classes in a single file

 
 
Aguilar, James
Guest
Posts: n/a
 
      07-14-2004
I know that one can define an essentially unlimited number of classes in a
file. And one can declare just as many in a header file. However, the
question I have is, should I?

Suppose that, to use the common example, I have a situation where I am
implementing many types of Shapes. My current way of thinking is, well,
since they are all the same type, let's just put them all in the same file.
The include file would be "shapes.h" and it would contain not just the base
class Shape, but also Curve, Arc, Circle, Polygon, Quadrilateral, Rhombus,
Square, Octagon, Pentagon, etc.

I am in a situation where I would potentially be creating hundreds of
subclasses, most of which would inherit more than ninety percent of their
functionality from parent classes. However, I do not know of any design
alternative that would not require me to define all these various classes
and subclasses, since certain ones of the subclass would require some very
specialized behavior. Also, I intend that this system of "Shapes" would be
very extensible.

I had thought of busting out a .dat file and reading it during the
initialization phase of my program to describe the behavior of these
objects. However, I am inexperienced, to say the least, and I'm not sure a
scripting language to describe behavior is the best use of time on a project
that is pretty small.

So, I want to avoid an excessive number of source files, but I want a lot of
classes. Do I have the right solution?


 
Reply With Quote
 
 
 
 
Senapathy
Guest
Posts: n/a
 
      07-14-2004

"Aguilar, James" <(E-Mail Removed)> wrote in message
news:cd2j3i$rk4$(E-Mail Removed)...
> I know that one can define an essentially unlimited number of classes in a
> file. And one can declare just as many in a header file. However, the
> question I have is, should I?
>
> Suppose that, to use the common example, I have a situation where I am
> implementing many types of Shapes. My current way of thinking is, well,
> since they are all the same type, let's just put them all in the same

file.
> The include file would be "shapes.h" and it would contain not just the

base
> class Shape, but also Curve, Arc, Circle, Polygon, Quadrilateral, Rhombus,
> Square, Octagon, Pentagon, etc.
>
> I am in a situation where I would potentially be creating hundreds of
> subclasses, most of which would inherit more than ninety percent of their
> functionality from parent classes. However, I do not know of any design
> alternative that would not require me to define all these various classes
> and subclasses, since certain ones of the subclass would require some very
> specialized behavior. Also, I intend that this system of "Shapes" would

be
> very extensible.
>
> I had thought of busting out a .dat file and reading it during the
> initialization phase of my program to describe the behavior of these
> objects. However, I am inexperienced, to say the least, and I'm not sure

a
> scripting language to describe behavior is the best use of time on a

project
> that is pretty small.
>
> So, I want to avoid an excessive number of source files, but I want a lot

of
> classes. Do I have the right solution?
>
>


My take on this subject (I don't know whether the experts would disagree!) :

About implementation files, I have my reservations about putting all the
classes' implementations into one file. You can easily split the
implementation into any number of files without sacrificing on end-user's
usability. The user of your classes can continue to include just 1 header
file of yours without needing to know which files they are implemented in.
If there are too many lines of code in 1 implementation file, it increases
the complexity of maintenance. Better to be modular.

Regarding header files, true that there is a convention that you should
declare only 1 class per header file. But there are precedences (doesn't
mean that they are necessarily right, but it just indicates that things are
not so drastically evil as it is made out to be, if you put multiple class
declarations in a header file)

I am giving a very platform specific example here. The MFC library has
numerous examples where a single header file declares many classes (if you
take a look at their collection classes, they are all declared in afxcoll.h,
numbering close to 20. Same is the case for the common control classes,
numbering nearly 20). Now the user has the convenience that he can include
just 1 header and start using multiple classes. If build time is a problem,
some compiler specific features could be there to reduce the build time.
(pre-compiled headers and pch files in VC++)

Senapathy


 
Reply With Quote
 
 
 
 
Aguilar, James
Guest
Posts: n/a
 
      07-14-2004

"Senapathy" <(E-Mail Removed)> wrote in message
news:cd2l4e$t0u$(E-Mail Removed)...
>
> [snip]


Followup question:

Won't having a whole bunch of different source files (say, put in a
subdirectory) be hell for the makefile? I can imagine a rule that says:

2dphysics.o: $(CCC) $(CFLAGS) ...(200 shape implementation files) shape.h

What do you do about that?


 
Reply With Quote
 
AVR
Guest
Posts: n/a
 
      07-14-2004
Aguilar, James wrote:

> "Senapathy" <(E-Mail Removed)> wrote in message
> news:cd2l4e$t0u$(E-Mail Removed)...
>
>>[snip]

>
>
> Followup question:
>
> Won't having a whole bunch of different source files (say, put in a
> subdirectory) be hell for the makefile? I can imagine a rule that says:
>
> 2dphysics.o: $(CCC) $(CFLAGS) ...(200 shape implementation files) shape.h
>
> What do you do about that?
>
>


I work on a project with quite a lot of implementation files. What is
usually done for these kinds of projects is use autoconf/automake to
generate the makefile for you. Organize your files into appropriate
subdirectories (if you want) and create a Makefile.am in each,
specifying the library it constitutes, and the sources in the directory
that you want to link. Autoconf/automake will do the makefile generation
for you, depending on your configuration settings.
Moreover, writing one or two lines in the makefile for each file you
write does not seem to be too much of a burden from my POV, if that's
what you were implying. After all, you need to do it just once per file.

regards,
AVR
 
Reply With Quote
 
Senapathy
Guest
Posts: n/a
 
      07-14-2004

"Aguilar, James" <(E-Mail Removed)> wrote in message
news:cd2m8j$sj8$(E-Mail Removed)...
>
> "Senapathy" <(E-Mail Removed)> wrote in message
> news:cd2l4e$t0u$(E-Mail Removed)...
> >
> > [snip]

>
> Followup question:
>
> Won't having a whole bunch of different source files (say, put in a
> subdirectory) be hell for the makefile? I can imagine a rule that says:
>
> 2dphysics.o: $(CCC) $(CFLAGS) ...(200 shape implementation files) shape.h
>
> What do you do about that?
>
>


I suppose, you meant the linking part.
Each source (implementation) file would contribute to 1 object file each. So
the make file would contain some 200 lines for producing these 200 .o files.
Hmm... the _linker_ would need some 200 object files.

But I suppose the IDE should remove the complexity from the build procedure.
Even a batch mode should not be too much of a problem if you want to
automate the build procedure. Some IDEs provide a mechanism to export a make
file from the present source file / header file list.

I would still prefer factored implementations because of the maintenace
aspect. Ultimately that would matter more than the build procedure.
If you have some source control / configuration management scheme, all these
things would not matter at all. Source code readability, maintainability
would server you in good stead.

However, since you mentioned that there would be around 200 implementation
files, maintaining these files also would prove cumbersome.
So I guess you need to arrive at a logical grouping of these files and club
some implementations together. I have done it also under some circumstances,
so I can't say it is such a bad thing either

Senapathy


 
Reply With Quote
 
JKop
Guest
Posts: n/a
 
      07-14-2004


I routed through my old code and whipped out the following. Here's the
header file:


// pso.hpp

#ifndef INCLUDE_PHYSICALSHAPEOBJECT_HPP
#define INCLUDE_PHYSICALSHAPEOBJECT_HPP

#include <cmath>

namespace PSO{


typedef long double MeasurementBuffer;


class PhysicalShapeObject
{
public:
virtual MeasurementBuffer GetVolume(void) const = 0;
virtual MeasurementBuffer GetSurfaceArea(void) const = 0;
};



class Sphere : public PhysicalShapeObject
{
public:
MeasurementBuffer GetVolume(void) const
{

return (

( radius * radius * radius )

* 4.0

* 3.14 //Pie

/ 3.0

);


}

MeasurementBuffer GetSurfaceArea(void) const
{
return (

( radius * radius )

* 4.0

* 3.14 //Pie

);
}

protected:

MeasurementBuffer radius;
};



class Cylinder : public PhysicalShapeObject
{
public:

MeasurementBuffer GetVolume(void) const
{
return (

( radius * radius )

* height

* 3.14 //Pie


);
}

MeasurementBuffer GetSurfaceArea(void) const
{
//This includes the two ends of the cylinder

return (

( 2.0 * height + radius ) //Might be dodgy!

* radius

* 3.14 //Pie

);
}

protected:

MeasurementBuffer radius;
MeasurementBuffer height;
};


class Cone : public PhysicalShapeObject
{
public:

MeasurementBuffer GetVolume(void) const
{
return (

( radius * radius )

* height

* 3.14 //Pie

/ 3.0

);
}

MeasurementBuffer GetSurfaceArea(void) const
{
//This includes the end of the cone

return (


(

std::sqrt(
( radius * radius )

+ ( height * height )

)//END OF std::sqrt

+ ( radius )

)


* ( radius )

* 3.14

);
}

MeasurementBuffer GetLength(void) const
{
return (

std::sqrt(

( radius * radius )

+ ( height*height )

)//END OF std::sqrt

);
}

protected:

MeasurementBuffer radius;
MeasurementBuffer height;
};


class Block : public PhysicalShapeObject
{
public:

MeasurementBuffer GetVolume(void) const
{
return (

length * width * depth

);
}

MeasurementBuffer GetSurfaceArea(void) const
{
return (
2 * (

( length*width )

+ ( length * depth )

+ ( width * depth )

)

);
}

protected:

MeasurementBuffer length;
MeasurementBuffer width;
MeasurementBuffer depth;
};


} //END OF NAMESPACE


#endif //INCLUDE_PHYSICALSHAPEOBJECT_HPP




And there ain't no source file!


-JKop
 
Reply With Quote
 
Gernot Frisch
Guest
Posts: n/a
 
      07-14-2004
> And there ain't no source file!

Yes, this is a very convenient method for small set's of classes that
do not get changed commonly. If however the file is quite huge or will
be changed commonly, you don't want to see the compilation times. I
use the Spirit++ parser generator (spirit.sf.net). It's a very huge
template library cosisting of headers only. Simple projects take very
long for compilation with it, although it's very convenient that you
only include a file and don't have to worry about any implementation
files.

-Gernot


 
Reply With Quote
 
Daniel T.
Guest
Posts: n/a
 
      07-14-2004
"Aguilar, James" <(E-Mail Removed)> wrote:

>I know that one can define an essentially unlimited number of classes in a
>file. And one can declare just as many in a header file. However, the
>question I have is, should I?


Here is a simple rule: If class A depends on class B and B depends on A,
put them in the same header file. If A and only A depends on B, put them
in the same header file. Otherwise put the two classes in different
header files.

>Suppose that, to use the common example, I have a situation where I am
>implementing many types of Shapes. My current way of thinking is, well,
>since they are all the same type, let's just put them all in the same file.
>The include file would be "shapes.h" and it would contain not just the base
>class Shape, but also Curve, Arc, Circle, Polygon, Quadrilateral, Rhombus,
>Square, Octagon, Pentagon, etc.


Follow the rule above "If Curve depends on Shape and Shape depends on
Curve, put them in the same header file. If Curve and only Curve depends
on Shape, put them in the same header file. Otherwise put them in
different header files." Apply this rule to every combination of classes.


>I am in a situation where I would potentially be creating hundreds of
>subclasses, most of which would inherit more than ninety percent of their
>functionality from parent classes. However, I do not know of any design
>alternative that would not require me to define all these various classes
>and subclasses, since certain ones of the subclass would require some very
>specialized behavior. Also, I intend that this system of "Shapes" would be
>very extensible.
>
>I had thought of busting out a .dat file and reading it during the
>initialization phase of my program to describe the behavior of these
>objects. However, I am inexperienced, to say the least, and I'm not sure a
>scripting language to describe behavior is the best use of time on a project
>that is pretty small.


You seem to be contradicting yourself, on the one hand you say you
"would potentially be creating hundreds of subclasses" on the other you
say your working on a "project that is pretty small." Those two
statements don't connect well for me.
 
Reply With Quote
 
Thomas Matthews
Guest
Posts: n/a
 
      07-14-2004
Aguilar, James wrote:
> I know that one can define an essentially unlimited number of classes in a
> file. And one can declare just as many in a header file. However, the
> question I have is, should I?
>
> Suppose that, to use the common example, I have a situation where I am
> implementing many types of Shapes. My current way of thinking is, well,
> since they are all the same type, let's just put them all in the same file.
> The include file would be "shapes.h" and it would contain not just the base
> class Shape, but also Curve, Arc, Circle, Polygon, Quadrilateral, Rhombus,
> Square, Octagon, Pentagon, etc.
>
> I am in a situation where I would potentially be creating hundreds of
> subclasses, most of which would inherit more than ninety percent of their
> functionality from parent classes. However, I do not know of any design
> alternative that would not require me to define all these various classes
> and subclasses, since certain ones of the subclass would require some very
> specialized behavior. Also, I intend that this system of "Shapes" would be
> very extensible.
>
> I had thought of busting out a .dat file and reading it during the
> initialization phase of my program to describe the behavior of these
> objects. However, I am inexperienced, to say the least, and I'm not sure a
> scripting language to describe behavior is the best use of time on a project
> that is pretty small.
>
> So, I want to avoid an excessive number of source files, but I want a lot of
> classes. Do I have the right solution?
>
>


I usually have one one class declared in a header file and
defined in a source file. I create directories / folders
to hold classes by theme. This helps with the maintenance
by having only one place to make one change. For example,
if I have class A & class B in a file, then if I change
class A, class B must also be recompiled. I like the
fact that I can get a class working, then not have to
recompile it due to changes in a non related class.

Another reason for one class one file is due to linker
resolution. Many Linkers have module scope as their
smallest resolution. If I have many classes defined
in a file and only want one, the linker will include
all the code for all the classes in that file (module
resolution). However, if I define only one class per
file, then I can only include the class I need and
not worry about extra code that I don't need.

In another thread, you ask about have many classes.
In this case, you can have libraries. Libraries are
collections of "object" files (the intermediary file
produced after compilation, but before linking).
This often speeds up the build process for classes
that don't change often. Many linkers support finer
resolution for library files than individual modules.
This may also alleviate symbol table overflow for
larger projects.

If you need multiple instances of classes at runtime
or the quantity varies at runtime, perhaps a factory
pattern is better suited. For example, one might
want a single Polygon class rather than pentagon,
hexagon, septagon and octagon classes. In this
case, you could create a hexagon instance by
specifying a 6 sided Polygon. All depends on your
project and your resources.

On the other hand, for small toy projects, I define
classes in one file until the quantity becomes
unwieldly. The effort and maintenance for multiple
files outweighs the time spent on the whole project.

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book

 
Reply With Quote
 
Marcelo Pinto
Guest
Posts: n/a
 
      07-14-2004
"Aguilar, James" <(E-Mail Removed)> wrote in message news:<cd2m8j$sj8$(E-Mail Removed)>...
> "Senapathy" <(E-Mail Removed)> wrote in message
> news:cd2l4e$t0u$(E-Mail Removed)...
> >
> > [snip]

>
> Followup question:
>
> Won't having a whole bunch of different source files (say, put in a
> subdirectory) be hell for the makefile? I can imagine a rule that says:
>
> 2dphysics.o: $(CCC) $(CFLAGS) ...(200 shape implementation files) shape.h
>
> What do you do about that?


[OT]
You don't have to make the dependencies explicitly (at least if you
are using gcc ). consider the following makefile:

[makefile]
VPATH = OBJ:lib

..SUFFIXES:
..SUFFIXES: .cc .o

CC = gcc $(FLAG_COMPILATION)
AR = ar

LIB = libutil.a

OBJS = MiscProcs.o \
Cronometer.o

..cc.o:
@echo ">>>>>>>>>>> $<"
@$(CC) -c $<

all: $(LIB)
-@mv -f *.o OBJ 2>/dev/null
-@mv -f *.a lib 2>/dev/null

$(LIB): $(OBJS)
-@mv -f *.o OBJ 2>/dev/null
-@mv -f OBJ/*.o . 2>/dev/null
@sleep 1
-@rm -f $@
-@$(AR) r $@ $(OBJS)

include depend.mk

depend:
gcc -MM *.cc > depend.mk
clean:
-rm -f lib/$(LIB) core

clobber: clean
-rm -f *.o OBJ/*.o
-rm -f *.a lib/*.a
[/makefile]

After you manage to compile MiscProcs.cc and Cronometer.cc correctly,
you run "make depend" and the gcc will fill the file depend.mk with
the dependency information.

[/OT]

Good luck,

Marcelo Pinto
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Defining nested Method in single class Arun Kumar Ruby 4 10-28-2010 10:15 AM
OOP casting classes (using one single variable for similar types of classes) roberts.noah@gmail.com C++ 8 01-07-2006 04:13 PM
defining or not defining destructors johny smith C++ 8 07-02-2004 08:51 AM
CSS - Syntax for defining Links with Classes Ben Amada HTML 8 01-16-2004 06:38 AM
Defining classes in jscript Henke ASP .Net 3 11-28-2003 04:18 PM



Advertisments