Redefinition Error

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • cody

    Redefinition Error

    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<cstrin g>
    using namespace std;
    class Literal;

    class Formula:public Control
    {
    public:

    virtual void print(ostream& os) const=0;
    virtual Formula* differentiate(c onst 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:publi c 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

  • John Harrison

    #2
    Re: Redefinition Error

    cody wrote:[color=blue]
    > 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<cstrin g>
    > using namespace std;
    > class Literal;
    >
    > class Formula:public Control
    > {
    > public:
    >
    > virtual void print(ostream& os) const=0;
    > virtual Formula* differentiate(c onst 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:publi c 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
    >[/color]

    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

    Comment

    • Alf P. Steinbach

      #3
      Re: Redefinition Error

      * cody:[color=blue]
      > Hello fols.[/color]

      Folks? Fools? What?

      [color=blue]
      > We're on virtual functions and have to seperate out each class into a file.[/color]

      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.

      [color=blue]
      > There are 9 classes and so 9 .h and .c files.[/color]

      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.

      [color=blue]
      > 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.[/color]

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

      [color=blue]
      > 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.[/color]

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

      [color=blue]
      > In main i had to include formula, variable, literal, and, or, xor.h.[/color]

      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.


      [color=blue]
      > Formula.h[/color]


      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.

      [color=blue]
      > #include <iostream>[/color]

      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.

      [color=blue]
      > #include "Control.h"
      > #include<cstrin g>
      > using namespace std;[/color]

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


      [color=blue]
      > class Literal;
      >
      > class Formula:public Control
      > {
      > public:
      >
      > virtual void print(ostream& os) const=0;[/color]

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

      [color=blue]
      > virtual Formula* differentiate(c onst string& var) const=0;[/color]

      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.

      [color=blue]
      > virtual bool evaluate(bool& val) const=0;
      > virtual Formula*subst() const=0;
      > virtual Formula*reduce( const string& var, const Literal* val) const=0;[/color]

      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?

      Comment

      • cody

        #4
        Re: Redefinition Error

        alfps@start.no (Alf P. Steinbach) wrote in
        news:432d0c76.6 21932703@news.i ndividual.net:
        [color=blue]
        > * cody:[color=green]
        >> Hello fols.[/color]
        >
        > Folks? Fools? What?
        >[/color]
        sorry lol ment to say folks. didnt spell check it enough ^.^[color=blue]
        >[color=green]
        >> We're on virtual functions and have to seperate out each class into a
        >> file.[/color]
        >
        > 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.
        >
        >[color=green]
        >> There are 9 classes and so 9 .h and .c files.[/color]
        >
        > 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.
        >
        >[color=green]
        >> 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.[/color]
        >
        > The top level doesn't make much sense: how is a formula a "control"?[/color]

        Control more or less keeps track of references to a formula. if a formula
        has no references then it is deleted.[color=blue]
        >
        >[color=green]
        >> 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.[/color]
        >
        > That is one problem, let's call it problem (A).
        >
        >[color=green]
        >> In main i had to include formula, variable, literal, and, or, xor.h.[/color]
        >
        > 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.
        >
        >
        >[color=green]
        >> Formula.h[/color]
        >
        >
        > 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.
        >
        >[color=green]
        >> #include <iostream>[/color]
        >
        > 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.
        >
        >[color=green]
        >> #include "Control.h"
        >> #include<cstrin g>
        >> using namespace std;[/color]
        >
        > Don't _ever_ put 'using namespace std;' in a header file.
        >
        >
        >[color=green]
        >> class Literal;
        >>
        >> class Formula:public Control
        >> {
        >> public:
        >>
        >> virtual void print(ostream& os) const=0;[/color]
        >
        > 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).[/color]

        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.[color=blue]
        >
        >[color=green]
        >> virtual Formula* differentiate(c onst string& var) const=0;[/color]
        >
        > 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.
        >
        >[color=green]
        >> virtual bool evaluate(bool& val) const=0;
        >> virtual Formula*subst() const=0;
        >> virtual Formula*reduce( const string& var, const Literal* val)
        >> const=0;[/color]
        >
        > Ditto.
        >
        > Hth.,
        >
        > - Alf
        >[/color]

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


        Comment

        Working...