Redefinition Error

Discussion in 'C++' started by cody, Sep 18, 2005.

  1. cody

    cody Guest

    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
     
    cody, Sep 18, 2005
    #1
    1. Advertising

  2. cody wrote:
    > 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
     
    John Harrison, Sep 18, 2005
    #2
    1. Advertising

  3. * 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

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Sep 18, 2005
    #3
  4. cody

    cody Guest

    (Alf P. Steinbach) wrote in
    news::

    > * cody:
    >> Hello fols.

    >
    > Folks? Fools? What?
    >

    sorry lol ment to say folks. didnt spell check it enough ^.^
    >
    >> 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"?


    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.
    >
    >
    >> 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
    >


    Thanks for the reply guys. i'll try the include guard again. I did it b4
    and wheeww it threw out lotsa errors.
     
    cody, Sep 18, 2005
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. A
    Replies:
    1
    Views:
    564
    Josephine Schafer
    Oct 22, 2003
  2. junaidnaseer
    Replies:
    4
    Views:
    757
    junaidnaseer
    May 9, 2006
  3. Robbie Hatley
    Replies:
    0
    Views:
    476
    Robbie Hatley
    Jun 28, 2006
  4. Robbie Hatley
    Replies:
    1
    Views:
    535
    Victor Bazarov
    Jun 28, 2006
  5. Robbie Hatley
    Replies:
    2
    Views:
    728
    Ian Collins
    Jun 29, 2006
Loading...

Share This Page