April 20, 2024, 08:08:04 AM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


Some Design Troubles

Started by Zen, December 13, 2005, 09:21:38 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Zen

I dont know what to do about this. Im sure i wont be the only person to try and do what im doing now so ill raise the question now.

This is all regarding OOP...

If i have a "Core" class lets say. I then have multiple classes that use the "Core" class as its base class to extend from. If i have each new class in a seperate file (to keep things tidy) and i want to include more than one of these new classes in my main file, i then get a duplicate definition error because the main class has been included more than once. If i take the include statement out of one of the class files i then get unknown base class ???

Its all very confusing but i dont know how to go about solving this problem. I would like to be able to do things this way as im used to doing designs like that in PHP, i know its differnt but i still like it.

Thanks
Lewis

Ionic Wind Support Team

Without seeing your code I can only guess.

Use the preprocessor.

#ifndef CORE_INCLUDED
#define CORE_INCLUDED

...class definition goes here

#endif

Then it doesn't matter how many times you try and include the same file, you'll never get a duplicate definition error.

Paul.
Ionic Wind Support Team

Zen

Hmm i dont think that will work. Here is some example code...

Main Source File:

#include "Classes/Database/MySQL_Def.inc";
//#include "Classes/Interface/Interface_Def.inc";

global sub main() {

MySQL myClass;

writeln("Aurora Common Classes Test Suite\n");
writeln("--------------------------------\n\n");

writeln("Version: " + myClass.GetSqlVersion() + "\n");

writeln("\nPress Any Key To Close");

while getkey() = "";

return;

}


MySQL_Def.inc:

#include "Classes/Base/Base_Def.inc";

class MySQL : Common {

declare GetSqlVersion(),string;
declare Connect(),int;
declare Disconnect();
declare ChangeDatabase(string name);
declare RunQuery(string sql),int;

}


Interface_Def.inc:

#include "Classes/Base/Base_Def.inc";

class Interface : Common {

declare Interface();
declare _Interface();

}


Both Classes include the Base class which handles things such as error reporting and will eventually include other things when i add more classes to my collection, that is why i am getting duplicate definitions of the base class if i un-comment out the second line in the main source file.

Hopefully this should be a little more understanding.

Lewis

Ionic Wind Support Team

You should also try and follow proper project design for include files.  Applies to all languages, not just Aurora.  Things like avoiding the common tendancy to put executable code in include files.

Include files should really only have definitions and constants.  Definitions are things like CLASS, STRUCT, DECLARE, #typedef, #ifdef, #ifndef, #define, etc.  None of those statements generate any code.

The preprocessor is designed specifically to resolve multiple inclusion conflicts.  Thats the purpose of having a #ifdef and #ifndef in the first place.  So use them liberally.

As for the implimentation of the class, meaning the actual code for each method, there are two generally followed models.  One class per source file or one method per source file.  Source files are cheap so when making a project try and separate things out as much as possible while keeping maintainability in mind. 

As for which model you follow it depends on the size of the class.  If the class has large methods, with pages of code for each method, then it's probably better to have one method per source file with descriptive names like 'myclass_method1.src', 'myclass_method2.src', etc.

It doesn't matter how many source files your class has.  The class definition will still be in one include file making it easy to use.

Paul.
Ionic Wind Support Team

Ionic Wind Support Team

Quote from: Lewis on December 13, 2005, 09:52:01 PM
Hmm i dont think that will work. Here is some example code...



It will work fine if you just try it.  It's the mainstay of OOP programming to use the preprocessor for just that reason.  In your 'Base_Def.inc' you woulld have:

#ifndef BASE_INCLUDED
#define BASE_INCLUDED

class common
{
...
}

#endif

Your duplicate definition is not coming from the the derived classes themselves, but the fact that they both include 'Base_def.inc' when read by your main source file.

Paul.
Ionic Wind Support Team

Zen

Thanks for clearing that up for me Paul. I did try what you put in your first reply, only i must of put something wrong. mybe i put #ifdef instead of #ifndef. It is 5:06am here so easy to make a mistake. :D

To be honest though ive never really used pre processor commands much before, onceor twice in IBasic for debugging but thats about it. So thats something i will have a play around with and get to know a bit better.

Thanks again.
Lewis

Ionic Wind Support Team

You just have to get a picture in your head what #include really does. 

In simple terms #include takes the contents of a file and pastes it into location of the #include statement.  Just as if you had copied and pasted it there yourself.  So lets expand your main source file statements:

#include "Classes/Database/MySQL_Def.inc";
#include "Classes/Interface/Interface_Def.inc";

Expands to


#include "Classes/Base/Base_Def.inc";

class MySQL : Common {

declare GetSqlVersion(),string;
declare Connect(),int;
declare Disconnect();
declare ChangeDatabase(string name);
declare RunQuery(string sql),int;

}

#include "Classes/Base/Base_Def.inc";

class Interface : Common {

declare Interface();
declare _Interface();

}


Which has two more include statments which then expands finally to:


class common
{
...
}

class MySQL : Common {

declare GetSqlVersion(),string;
declare Connect(),int;
declare Disconnect();
declare ChangeDatabase(string name);
declare RunQuery(string sql),int;

}

class common
{
...
}

class Interface : Common {

declare Interface();
declare _Interface();

}

global sub main() {

MySQL myClass;

writeln("Aurora Common Classes Test Suite\n");
writeln("--------------------------------\n\n");

writeln("Version: " + myClass.GetSqlVersion() + "\n");

writeln("\nPress Any Key To Close");

while getkey() = "";

return;

}


Hence you get the duplicate definition error.  Using #ifndef/#define tells the compiler not to include the contents of 'base_def.inc' the second time around. 

Paul.

Ionic Wind Support Team

Zen

I never thought of it that way. I knew what it did but i guess i just didnt think about what i was doing to the extent of figuring out what would end up where when the compiler runs. ::)

At least now i know what problems to look out for.

Thanks again Paul :D
Lewis