472,326 Members | 1,327 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,326 software developers and data experts.

Defining many classes in a single file

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?
Jul 22 '05 #1
9 6501

"Aguilar, James" <jf**@cec.NOBOTSwustl.edu> wrote in message
news:cd**********@newsreader.wustl.edu...
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
Jul 22 '05 #2

"Senapathy" <se*********@siemens.com> wrote in message
news:cd**********@news.mch.sbs.de...

[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?
Jul 22 '05 #3
AVR
Aguilar, James wrote:
"Senapathy" <se*********@siemens.com> wrote in message
news:cd**********@news.mch.sbs.de...
[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
Jul 22 '05 #4

"Aguilar, James" <jf**@cec.NOBOTSwustl.edu> wrote in message
news:cd**********@newsreader.wustl.edu...

"Senapathy" <se*********@siemens.com> wrote in message
news:cd**********@news.mch.sbs.de...

[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
Jul 22 '05 #5


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
Jul 22 '05 #6
> 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
Jul 22 '05 #7
"Aguilar, James" <jf**@cec.NOBOTSwustl.edu> 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.
Jul 22 '05 #8
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

Jul 22 '05 #9
"Aguilar, James" <jf**@cec.NOBOTSwustl.edu> wrote in message news:<cd**********@newsreader.wustl.edu>...
"Senapathy" <se*********@siemens.com> wrote in message
news:cd**********@news.mch.sbs.de...

[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
Jul 22 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Miranda Evans | last post by:
Seeking reference material (a url, a book, an article) that offers advice and guidelines for organizing classes within files. For example, assume...
0
by: Brian van den Broek | last post by:
Hi all, IDLE refuses to launch, and I believe it is because I attempted to define a custom key-binding that it doesn't like. I was recently...
1
by: Erik Max Francis | last post by:
I've come across a limitation in unpickling certain types of complex data structures which involve instances that override __hash__, and was...
45
by: Steven T. Hatton | last post by:
This is a purely *hypothetical* question. That means, it's /pretend/, CP. ;-) If you were forced at gunpoint to put all your code in classes,...
7
by: Patrick | last post by:
Hi all, I was playing around with ASP.Net 2.0 and recognized that in case you use Code-Behind/Beside (how is it called in future?) the parser...
11
by: John Salerno | last post by:
From my brief experience with C#, I learned that it was pretty standard practice to put each class in a separate file. I assume this is a benefit...
26
by: Cliff Williams | last post by:
Can someone explain the pros/cons of these different ways of creating a class? // 1 function myclass() { this.foo1 = function() {...} } ...
2
by: =?Utf-8?B?Z2FkeWE=?= | last post by:
I use one of 2 arrays dependent on the country. Rather than say: if exchangeID = 1 then dim myPlaceBets() as As UK.exchange.PlaceBets many...
12
by: Janaka Perera | last post by:
Hi All, We have done a object oriented design for a system which will create a class multiply inherited by around 1000 small and medium sized...
0
by: tammygombez | last post by:
Hey everyone! I've been researching gaming laptops lately, and I must say, they can get pretty expensive. However, I've come across some great...
0
by: concettolabs | last post by:
In today's business world, businesses are increasingly turning to PowerApps to develop custom business applications. PowerApps is a powerful tool...
0
better678
by: better678 | last post by:
Question: Discuss your understanding of the Java platform. Is the statement "Java is interpreted" correct? Answer: Java is an object-oriented...
0
by: teenabhardwaj | last post by:
How would one discover a valid source for learning news, comfort, and help for engineering designs? Covering through piles of books takes a lot of...
0
by: Naresh1 | last post by:
What is WebLogic Admin Training? WebLogic Admin Training is a specialized program designed to equip individuals with the skills and knowledge...
0
jalbright99669
by: jalbright99669 | last post by:
Am having a bit of a time with URL Rewrite. I need to incorporate http to https redirect with a reverse proxy. I have the URL Rewrite rules made...
0
by: antdb | last post by:
Ⅰ. Advantage of AntDB: hyper-convergence + streaming processing engine In the overall architecture, a new "hyper-convergence" concept was...
0
by: Matthew3360 | last post by:
Hi there. I have been struggling to find out how to use a variable as my location in my header redirect function. Here is my code. ...
0
by: AndyPSV | last post by:
HOW CAN I CREATE AN AI with an .executable file that would suck all files in the folder and on my computerHOW CAN I CREATE AN AI with an .executable...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.