Redefinition Error

C

cody

Hello fols. I'm doin a school project and have this stupid problem. We're
on virtual functions and have to seperate out each class into a file. There
are 9 classes and so 9 .h and .c files. the file structure is something
like this.

control
|
formula
|| |
|| |
|| Operation
|variable |||
literal ||AND
|XOR
OR

So formula inherits from control and operation from formula and etc. Well
each of those classes would have an include for their parent and that's the
problem i'm having. I've compiled the 9 classes, but the main keeps giving
me that redefinition error. In main i had to include formula, variable,
literal, and, or, xor.h.

Formula.h
#include <iostream>
#include "Control.h"
#include<cstring>
using namespace std;
class Literal;

class Formula:public Control
{
public:

virtual void print(ostream& os) const=0;
virtual Formula* differentiate(const string& var) const=0;
virtual bool evaluate(bool& val) const=0;
virtual Formula*subst() const=0;
virtual Formula*reduce(const string& var, const Literal* val) const=0;

Control.h
public:
void addRef();
void removeRef() ;

private:
int refCount;

protected:
Control(void);
virtual ~Control(void){;}

===============================================================
Literal.h
#include <iostream>
#include <cstring>
#include "Formula.h"
using namespace std;

class Literal : public Formula
{
private:

bool value;

public:

Literal(bool v);
~Literal(void);
void print(ostream& os) const;
bool evaluate(bool& val) const;
Formula* reduce(void) const;
Formula* differentiate( const string& val ) const;
Formula* subst(const string& var, const Literal* val) const;

};
=======================================================================

Operation.h
#include <iostream>
using namespace std;
#include "Formula.h"

class Operation:public Formula
{
public:

protected:
Operation( Formula* l=0, Formula* r=0);
~Operation(void);
Formula * left;
Formula * right;
};

=======================================================================
And.h
#include <iostream>
#include "Operation.h"
using namespace std;

class And : public Operation
{
public:

And(Formula* l, Formula*r): Operation(l,r){}
void print(ostream& os) const;
bool evaluate(bool& val) const;
Formula* reduce(void) const;
Formula* differentiate( const string& var ) const;

};

Thanks in advance
 
J

John Harrison

cody said:
Hello fols. I'm doin a school project and have this stupid problem. We're
on virtual functions and have to seperate out each class into a file. There
are 9 classes and so 9 .h and .c files. the file structure is something
like this.

control
|
formula
|| |
|| |
|| Operation
|variable |||
literal ||AND
|XOR
OR

So formula inherits from control and operation from formula and etc. Well
each of those classes would have an include for their parent and that's the
problem i'm having. I've compiled the 9 classes, but the main keeps giving
me that redefinition error. In main i had to include formula, variable,
literal, and, or, xor.h.

Formula.h
#include <iostream>
#include "Control.h"
#include<cstring>
using namespace std;
class Literal;

class Formula:public Control
{
public:

virtual void print(ostream& os) const=0;
virtual Formula* differentiate(const string& var) const=0;
virtual bool evaluate(bool& val) const=0;
virtual Formula*subst() const=0;
virtual Formula*reduce(const string& var, const Literal* val) const=0;

Control.h
public:
void addRef();
void removeRef() ;

private:
int refCount;

protected:
Control(void);
virtual ~Control(void){;}

===============================================================
Literal.h
#include <iostream>
#include <cstring>
#include "Formula.h"
using namespace std;

class Literal : public Formula
{
private:

bool value;

public:

Literal(bool v);
~Literal(void);
void print(ostream& os) const;
bool evaluate(bool& val) const;
Formula* reduce(void) const;
Formula* differentiate( const string& val ) const;
Formula* subst(const string& var, const Literal* val) const;

};
=======================================================================

Operation.h
#include <iostream>
using namespace std;
#include "Formula.h"

class Operation:public Formula
{
public:

protected:
Operation( Formula* l=0, Formula* r=0);
~Operation(void);
Formula * left;
Formula * right;
};

=======================================================================
And.h
#include <iostream>
#include "Operation.h"
using namespace std;

class And : public Operation
{
public:

And(Formula* l, Formula*r): Operation(l,r){}
void print(ostream& os) const;
bool evaluate(bool& val) const;
Formula* reduce(void) const;
Formula* differentiate( const string& var ) const;

};

Thanks in advance

You need to use the 'include guard' trick.

// And.h
#ifndef AND_H
#define AND_H

contents of And.h here

#endif

// Operation.h
#ifndef OPERATION_H
#define OPERATION_H

contents of Operation.h here

#endif

etc. etc.

This stops your header files from being compiled more than once in the
same compilation which I think is the problem you're describing above.
Every header file you write should use include guards.

This trick doesn't stop headers being compiled more than once in
different complations though, nothing could do that, which is what some
newbies seems to think.

john
 
A

Alf P. Steinbach

* cody:
Hello fols.

Folks? Fools? What?

We're on virtual functions and have to seperate out each class into a file.

That's not always a good idea.

Anyway, that's _physical packaging_ of the code.

The logical structure of the code is mostly independent of physical packaging.

There are 9 classes and so 9 .h and .c files.

For C++ it's a good idea to choose a different file name suffix for
implementation file than for C, e.g., use .cpp instead of .c.

the file structure is something like this.

control
|
formula
|| |
|| |
|| Operation
|variable |||
literal ||AND
|XOR
OR

So formula inherits from control and operation from formula and etc.

The top level doesn't make much sense: how is a formula a "control"?

Well
each of those classes would have an include for their parent and that's the
problem i'm having. I've compiled the 9 classes, but the main keeps giving
me that redefinition error.

That is one problem, let's call it problem (A).

In main i had to include formula, variable, literal, and, or, xor.h.

That is another problem, let's call it problem (B).

You haven't described what problem (A) is exactly, so no answer is possible
there.

For problem (B), simply create a header file, like, [expression.h], that
includes the relevant other header files.


Formula.h


At this point you should have an _include guard_, e.g. as follows (simplest
possible):

#ifndef FORMULA_H
#define FORMULA_H

and then at the very end of the file,

#endif

Just doing this _may_ seem to solve your problem (A).

But it wouldn't really be a solution of that problem until you identified
exactly what caused the problem, and could reproduce the problem.

#include <iostream>

In general, only do i/o in classes _dedicated_ to i/o, and nowhere else.
Otherwise your classes will be not very much reusable (e.g., in a graphical
user interface). And, too complex to discuss here, i/o creates a lot of other
problems, directly and indirectly.

#include "Control.h"
#include<cstring>
using namespace std;

Don't _ever_ put 'using namespace std;' in a header file.


class Literal;

class Formula:public Control
{
public:

virtual void print(ostream& os) const=0;

As mentioned, it's not a good idea to do i/o here. Instead consider a
conversion to string. Or something -- separation of concerns (consider how
this class could be used in a windowing application).

virtual Formula* differentiate(const string& var) const=0;

That's a raw pointer I see there in the result type. Is it a pointer to an
array or to a single object? How long is it valid? Who is responsible for
deallocation? Better make it a std::auto_ptr or some such.

virtual bool evaluate(bool& val) const=0;
virtual Formula*subst() const=0;
virtual Formula*reduce(const string& var, const Literal* val) const=0;

Ditto.

Hth.,

- Alf
 
C

cody

(e-mail address removed) (Alf P. Steinbach) wrote in

* cody:

Folks? Fools? What?
sorry lol ment to say folks. didnt spell check it enough ^.^
That's not always a good idea.

Anyway, that's _physical packaging_ of the code.

The logical structure of the code is mostly independent of physical
packaging.



For C++ it's a good idea to choose a different file name suffix for
implementation file than for C, e.g., use .cpp instead of .c.



The top level doesn't make much sense: how is a formula a "control"?

Control more or less keeps track of references to a formula. if a formula
has no references then it is deleted.
Well
each of those classes would have an include for their parent and
that's the problem i'm having. I've compiled the 9 classes, but the
main keeps giving me that redefinition error.

That is one problem, let's call it problem (A).

In main i had to include formula, variable, literal, and, or, xor.h.

That is another problem, let's call it problem (B).

You haven't described what problem (A) is exactly, so no answer is
possible there.

For problem (B), simply create a header file, like, [expression.h],
that includes the relevant other header files.


Formula.h


At this point you should have an _include guard_, e.g. as follows
(simplest possible):

#ifndef FORMULA_H
#define FORMULA_H

and then at the very end of the file,

#endif

Just doing this _may_ seem to solve your problem (A).

But it wouldn't really be a solution of that problem until you
identified exactly what caused the problem, and could reproduce the
problem.

#include <iostream>

In general, only do i/o in classes _dedicated_ to i/o, and nowhere
else. Otherwise your classes will be not very much reusable (e.g., in
a graphical user interface). And, too complex to discuss here, i/o
creates a lot of other problems, directly and indirectly.

#include "Control.h"
#include<cstring>
using namespace std;

Don't _ever_ put 'using namespace std;' in a header file.


class Literal;

class Formula:public Control
{
public:

virtual void print(ostream& os) const=0;

As mentioned, it's not a good idea to do i/o here. Instead consider a
conversion to string. Or something -- separation of concerns
(consider how this class could be used in a windowing application).

i woulda used string or something if i could, but all the function
protypes were specified by the prof so I gotta work around em.
That's a raw pointer I see there in the result type. Is it a pointer
to an array or to a single object? How long is it valid? Who is
responsible for deallocation? Better make it a std::auto_ptr or some
such.



Ditto.

Hth.,

- Alf

Thanks for the reply guys. i'll try the include guard again. I did it b4
and wheeww it threw out lotsa errors.
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top