0

First, I know that this problem has already been treated here, but I have not been able to solve it.

I have several classes, which are LitteralPart, Monome, Polynome and PolynomialFraction. They all have to be able to use each other, (i.e. Monome have to be able to owns methods which could return PolynomialFraction), but when I try to compile the program, I get around 400 like

"Polynome" does not name a type
"Monome" is not declared
"LitteralPart" is not declared in this scope

and so on.

Each of headers file are as the following :

#ifndef // Variable for the file
#define // Variable for the file

#include "includes.h" // Contains several includes like <QString> or <QVector>

#include // All others class headers

class Class
{
   // Class definition
};

// Operators overloading

For example, here is the Polynome header with all errors in comment :

#ifndef POLYNOME_H
#define POLYNOME_H

#include "includes.h"

#include "monome.h"
#include "polynomialfraction.h"
#include "math.h"

class Polynome
{
public:
    Polynome();
    Polynome(QString polynome);

    void setMonomeVector(QVector<Monome> monomeVector);
        /*
           "Monome" was not declared in this scope
            template argument 1 is invalid
            "Monome" was not declared in this scope
            template argument 1 is invalid
            "Monome" was not declared in this scope
            template argument 1 is invalid
            "Monome" was not declared in this scope
            template argument 1 is invalid
            "Monome" was not declared in this scope
            template argument 1 is invalid
        */

    QVector<Monome> getMonomeVector()const;
        /*
           "Monome" was not declared in this scope
            template argument 1 is invalid
            "Monome" was not declared in this scope
            template argument 1 is invalid
            "Monome" was not declared in this scope
            template argument 1 is invalid
            "Monome" was not declared in this scope
            template argument 1 is invalid
            "Monome" was not declared in this scope
            template argument 1 is invalid
        */

    int getConstantValue();
    QStringList getLitteralParts() const;

    void simplify();
    void invert();

    int getDegree() const;
    QString toString()const;

    void operator+=(Monome const& other);
        /*
            "Monome" has not been declared
            "Monome" has not been declared
            "Monome" has not been declared
            "Monome" has not been declared
            "Monome" has not been declared
         */
    void operator+=(Polynome const& other);

    void operator-=(Monome const& other);
        /*
            "Monome" has not been declared
            "Monome" has not been declared
            "Monome" has not been declared
            "Monome" has not been declared
            "Monome" has not been declared
         */
    void operator-=(Polynome const& other);

    void operator*=(int const& other);
        /*
            with "void operator*=(int const& other)";
            with "void operator*=(int const& other)";
            with "void operator*=(int const& other)";
            with "void operator*=(int const& other)";
            with "void operator*=(int const& other)";
         */
    void operator*=(Monome const& other);
        /*
            "Monome" has not been declared
            "Monome" has not been declared
            "Monome" has not been declared
            "Monome" has not been declared
            "Monome" has not been declared
         */
    void operator*=(Polynome const& other);

    void operator/=(int const& other);
        /*
            with "void operator/=(int const& other)";
            with "void operator/=(int const& other)";
            with "void operator/=(int const& other)";
            with "void operator/=(int const& other)";
            with "void operator/=(int const& other)";
        */
    void operator/=(Monome const& other);
        /*
            "Monome" has not been declared
            "Monome" has not been declared
            "Monome" has not been declared
            "Monome" has not been declared
            "Monome" has not been declared
         */
    void operator/=(Polynome const& other);

    void operator=(QString const& value);
    void operator=(const char* value);

private:
    QVector<Monome> monomeVector;
        /*
           "Monome" was not declared in this scope
            template argument 1 is invalid
            "Monome" was not declared in this scope
            template argument 1 is invalid
            "Monome" was not declared in this scope
            template argument 1 is invalid
            "Monome" was not declared in this scope
            template argument 1 is invalid
            "Monome" was not declared in this scope
            template argument 1 is invalid
        */
};

Polynome operator+(Polynome const& a, Monome const& b);
    /*
        "Monome" has not been declared
        "Monome" has not been declared
        "Monome" has not been declared
        "Monome" has not been declared
        "Monome" has not been declared
    */
Polynome operator+(Polynome const& a, Polynome const& b);

Polynome operator-(Polynome const& a, Monome const& b);
    /*
        "Monome" has not been declared
        "Monome" has not been declared
        "Monome" has not been declared
        "Monome" has not been declared
        "Monome" has not been declared
     */
Polynome operator-(Polynome const& a, Polynome const& b);
Polynome operator*(Polynome const& a, int const& b);
Polynome operator*(int const& b, Polynome const& a);
Polynome operator*(Polynome const& a, int const& b);
Polynome operator*(Polynome const& a, Monome const& b);
    /*
        "Monome" has not been declared
        "Monome" has not been declared
        "Monome" has not been declared
        "Monome" has not been declared
        "Monome" has not been declared
     */
Polynome operator*(Polynome const& a, Polynome const& b);

Polynome operator/(Polynome const& a, int const& b);
Polynome operator/(int const& b, Polynome const& a);
Polynome operator/(Polynome const& a, Monome const& b);
    /*
        "Monome" has not been declared
        "Monome" has not been declared
        "Monome" has not been declared
        "Monome" has not been declared
        "Monome" has not been declared
     */
Polynome operator/(Monome const& b, Polynome const& a);
    /*
        "Monome" has not been declared
        "Monome" has not been declared
        "Monome" has not been declared
        "Monome" has not been declared
        "Monome" has not been declared
     */
Polynome operator/(Polynome const& a, Polynome const& b);

#endif // POLYNOME_H

There are the same problems in all others files.

All those files, except includes.h have been placed in a subdirectory of the project, but if I use #include "polynome.h", #include "variables/polynome.h" or even their absolute path, that changes nothing.

Thechi2000
  • 35
  • 6
  • In your posted code, you don't have a semicolor (`;`) to end the class definition. Is that a typo in posting your code, or is that missing in the code on your computer too? – R Sahu Apr 16 '20 at 22:18
  • 2
    Seems like a problem of cyclical includes. `a.h` includes `b.h`, which includes `c.h`, which includes `a.h` again. You have to break the cycle somehow. – john Apr 16 '20 at 22:19
  • For the semicolon, this is just a typo. – Thechi2000 Apr 16 '20 at 22:21
  • Could you explain me how to break the cycle please ? – Thechi2000 Apr 16 '20 at 22:22
  • 1
    Google "c++ forward declaration" to get ahead. Do check spelling, just in case, proper terms are "polynomial", "monomial" and "literal". – Hans Passant Apr 16 '20 at 22:25
  • 1
    Forward declarations or interfaces are used to break cyclic dependencies. – Thomas Sablik Apr 16 '20 at 22:26
  • 1
    I can't explain in detail without seeing the code, and it's not likely to be easy. But what I would do is place all these interrelated classes into a single header file. Get all the classes and methods declared using forward declarations where necessary. And then later in the header file define any methods you want defined with out of class explicitly inlined definitions. – john Apr 16 '20 at 22:26
  • @Thechi2000 Having done all that, if you then want to split into separate header files again, you'll find it much easier. Just don't recreate the cycle of includes. – john Apr 16 '20 at 22:37
  • I highly recommend using class names that differ from keywords, both in spelling and case. – Thomas Matthews Apr 16 '20 at 22:56
  • @john How do I prevent from recreating the cycle if I want to resplit them ? – Thechi2000 Apr 16 '20 at 23:01
  • @Thechi2000 If you have successfully put them into a single header file then you will have worked out an *order* in which you can declare the various classes. You can use that order to split up the header file. So suppose in your combined header file `class Litteral` is first, then you can move that class to `"Literal.h"` and put `#include "Literal.h"` in your combined header file.. Then repeat this process with the class that is now the first in your combined header file. – john Apr 17 '20 at 05:33
  • The part after the **Edit:** looks like an answer. So, you may make it a [self-answer](https://stackoverflow.com/help/self-answer) or just delete your question. Actually, there are already Q/As about cyclic dependencies in SO. It's one of the common issues in C++ (and other languages). – Scheff's Cat Apr 17 '20 at 05:39

1 Answers1

0

I have put (and renamed) all my classes declarations together, so I have :

#ifndef VARIABLESINCLUDE_H
#define VARIABLESINCLUDE_H

#include "includes.h"
#include "math.h"

class Litteral;
class Monomial;
class Polynomial;
class PolynomialFraction;

class Litteral
{
public:
    Litteral();
    Litteral(QString value);

    QString toString() const;

    void invert();

    void setLitteral(QString litteral);
    void setExposant(int exposant);

    QString getLitteral() const;
    int getExposant() const;

    QString operator+(Litteral a);

private:
    QString litteral;
    int exposant;
};

bool operator==(Litteral const& a, Litteral const& b);
bool operator!=(Litteral const& a, Litteral const& b);

class Monomial
{
public:
    Monomial();
    Monomial(QString monome);

    QStringList getLitterals() const;

    QString toAbsoluteValueString() const;
    QString toString() const;

    void invert();

    void operator*=(int other);
    void operator*=(Litteral other);
    void operator*=(Monomial other);

    void operator/=(int const& other);
    void operator/=(Litteral const& other);
    void operator/=(Monomial const& other);

    void setCoefficient(int coefficient);
    void setLitteralVector(QVector<Litteral> litteralPartVector);
    void addLitteral(Litteral litteralPart);

    bool isNull() const;
    int getMaxPower() const;
    int getDegree() const;
    int getCoefficient() const;
    QVector<Litteral> getLitteralVector() const;

    void simplify();

private:
    QVector<Litteral> litteralPartVector;
    int coefficient;
};

Monomial operator*(Monomial const& a, int const& b);
Monomial operator*(Monomial const& a, Litteral const& b);
Monomial operator*(Monomial const& a, Monomial const& b);

Monomial operator/(Monomial const& a, int const& b);
Monomial operator/(Monomial const& a, Litteral const& b);
Monomial operator/(Monomial const& a, Monomial const& b);

class Polynomial
{
public:
    Polynomial();
    Polynomial(QString polynome);

    void setMonomialVector(QVector<Monomial> monomeVector);

    QVector<Monomial> getMonomialVector()const;
    int getConstantValue();
    QStringList getLitterals() const;

    void simplify();
    void invert();

    int getDegree() const;
    QString toString()const;

    void operator+=(Monomial const& other);
    void operator+=(Polynomial const& other);

    void operator-=(Monomial const& other);
    void operator-=(Polynomial const& other);

    void operator*=(int const& other);
    void operator*=(Monomial const& other);
    void operator*=(Polynomial const& other);

    void operator/=(int const& other);
    void operator/=(Monomial const& other);
    void operator/=(Polynomial const& other);

    void operator=(QString const& value);
    void operator=(const char* value);

private:
    QVector<Monomial> monomeVector;
};

Polynomial operator+(Polynomial const& a, Monomial const& b);
Polynomial operator+(Polynomial const& a, Polynomial const& b);

Polynomial operator-(Polynomial const& a, Monomial const& b);
Polynomial operator-(Polynomial const& a, Polynomial const& b);
Polynomial operator*(Polynomial const& a, int const& b);
Polynomial operator*(int const& b, Polynomial const& a);
Polynomial operator*(Polynomial const& a, int const& b);
Polynomial operator*(Polynomial const& a, Monomial const& b);
Polynomial operator*(Polynomial const& a, Polynomial const& b);

Polynomial operator/(Polynomial const& a, int const& b);
Polynomial operator/(int const& b, Polynomial const& a);
Polynomial operator/(Polynomial const& a, Monomial const& b);
Polynomial operator/(Monomial const& b, Polynomial const& a);
Polynomial operator/(Polynomial const& a, Polynomial const& b);

class PolynomialFraction
{
public:
    PolynomialFraction();
    PolynomialFraction(Polynomial numerator);
    PolynomialFraction(Polynomial numerator, Polynomial denominator);
    PolynomialFraction(QString numerator);
    PolynomialFraction(QString numerator, QString denominator);
    PolynomialFraction(const char* numerator);
    PolynomialFraction(const char* numerator, const char* denominator);

    QString toString() const;

    void invert();

    Polynomial getNumerator() const;
    Polynomial getDenominator() const;

    void setNumerator(Polynomial numerator);
    void setDenominator(Polynomial denominator);

    void operator+=(int const& other);
    void operator+=(Monomial const& other);
    void operator+=(Polynomial const& other);
    void operator+=(PolynomialFraction const& other);

    void operator-=(int const& other);
    void operator-=(Monomial const& other);
    void operator-=(Polynomial const& other);
    void operator-=(PolynomialFraction const& other);

    void operator*=(int const& other);
    void operator*=(Monomial const& other);
    void operator*=(Polynomial const& other);
    void operator*=(PolynomialFraction const& other);

    void operator/=(int const& other);
    void operator/=(Monomial const& other);
    void operator/=(Polynomial const& other);
    void operator/=(PolynomialFraction const& other);

    void operator=(QString const& value);
    void operator=(char* const value);

private:
    Polynomial numerator, denominator;
};

PolynomialFraction operator+(PolynomialFraction const& a, int const& b);
PolynomialFraction operator+(PolynomialFraction const& a, Monomial const& b);
PolynomialFraction operator+(PolynomialFraction const& a, Polynomial const& b);
PolynomialFraction operator+(int const& b, PolynomialFraction const& a);
PolynomialFraction operator+(Monomial const& b, PolynomialFraction const& a);
PolynomialFraction operator+(Polynomial const& b, PolynomialFraction const& a);
PolynomialFraction operator+(PolynomialFraction const& a, PolynomialFraction const& b);

PolynomialFraction operator-(PolynomialFraction const& a, int const& b);
PolynomialFraction operator-(PolynomialFraction const& a, Monomial const& b);
PolynomialFraction operator-(PolynomialFraction const& a, Polynomial const& b);
PolynomialFraction operator-(int const& b, PolynomialFraction const& a);
PolynomialFraction operator-(Monomial const& b, PolynomialFraction const& a);
PolynomialFraction operator-(Polynomial const& b, PolynomialFraction const& a);
PolynomialFraction operator-(PolynomialFraction const& a, PolynomialFraction const& b);

PolynomialFraction operator*(PolynomialFraction const& a, int const& b);
PolynomialFraction operator*(PolynomialFraction const& a, Monomial const& b);
PolynomialFraction operator*(PolynomialFraction const& a, Polynomial const& b);
PolynomialFraction operator*(int const& b, PolynomialFraction const& a);
PolynomialFraction operator*(Monomial const& b, PolynomialFraction const& a);
PolynomialFraction operator*(Polynomial const& b, PolynomialFraction const& a);
PolynomialFraction operator*(PolynomialFraction const& a, PolynomialFraction const& b);

PolynomialFraction operator/(PolynomialFraction const& a, int const& b);
PolynomialFraction operator/(PolynomialFraction const& a, Monomial const& b);
PolynomialFraction operator/(PolynomialFraction const& a, Polynomial const& b);
PolynomialFraction operator/(int const& b, PolynomialFraction const& a);
PolynomialFraction operator/(Monomial const& b, PolynomialFraction const& a);
PolynomialFraction operator/(Polynomial const& b, PolynomialFraction const& a);
PolynomialFraction operator/(PolynomialFraction const& a, PolynomialFraction const& b);

#endif // VARIABLESINCLUDE_H

Then, in all .cpp files, I replaced #include "polynome.h" by #include "variablesinclude.h". That solved the problem.

Thechi2000
  • 35
  • 6