Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 15/03/2011, à 19:23

Maneithel

[RÉSOLU]QtCreator, Qt, C++ Étrange undefined reference to 'function()'

Bonjour !
Je développe un petit logiciel qui utilise certaines fonctionS mathématiques (j'en suis à faire compiler ces maths).

J'ai une classe Mathematic qui contient des méthodes statiques (je devrais peut-être ne pas avoir une classe mais plutôt un namespace, mais c'est pour être cohérent avec le code pourri de mon enseignant).

J'ai une classe Vector3d qui contient un méthode fuzz qui utilise Mathematic::Random.  C'est la seule utilisation de cette méthode (Random).  Mon compilateur (gcc) m'informe qu'à cet endroit il y a un

undefined reference to 'Mathematic::Random()'

Or, la fonction est bel et bien déclarée et bel et bien définie dans respectivement mathematic.h et mathematic.cpp.
Je vous envoie des bouts de code.

Voici don la déclaration de Mathematic (mathematic.h)

#include <math.h>

#include "macro.h"

#include "angle.h"
#include "vector3d.h"
#include "matrix4d.h"

class Radian;
class Degree;
class Angle;
class Vector3d;
class Matrix4d;

class Mathematic
{
public:
    Mathematic();

    inline static Radian DegreeToRadian(const Degree &d);
    inline static Degree RadianToDegree(const Radian &r);

    inline static int   Randomize();

// DECLARATION DE MATHEMATIC::RANDOM() ******
    inline static float Random();
    inline static int RandomIntegerBetween( int min, int max );
    inline static float Round(float value, int precision);
    static void Unproject(Vector3d& Origin,
                          Vector3d& Direction,
                          const Vector3d& Position2D,
                          const Matrix4d& ViewInverse,
                          const Matrix4d& Projection,
                          int ScreenWidth,
                          int ScreenHeight);

    template <typename T>
            static T Clamp(T val, T min, T max)
    {
        return std::max(std::min(val, max), min);
    }
};

et la définition (mathematic.cpp)

#include "mathematic.h"


Mathematic::Mathematic()
{
}

inline Radian Mathematic::DegreeToRadian(const Degree &d)
{
    return Radian(d.valueDegrees() * DEG2RAD);
}

inline Degree Mathematic::RadianToDegree(const Radian &r)
{
    return Radian(r.valueRadians() * RAD2DEG);
}

inline int   Mathematic::Randomize(void)
{
        int LastRandom = 0;
        if (LastRandom == 0)
                srand((unsigned)time(NULL));
        int RandNum = (rand() + LastRandom) % RAND_MAX;
        LastRandom = RandNum;
        return(RandNum);
}

// DEFINITION DE MATHEMATIC::RANDOM() **********
inline float Mathematic::Random(void)
{
        return(static_cast<float>(Randomize()) / (float)RAND_MAX);
}

inline int Mathematic::RandomIntegerBetween( int min, int max )
{
        if( max <= min ) return min;

        int val =  min + rand() % ( max - min + 1 );

        if( val > max ) val = max;

        return val;
}

inline float Mathematic::Round(float value, int precision)
{
        float alpha = value;
        int   beta = 1;

        for(int i=0;i<precision;i++)
                beta *= 10;

        alpha *= beta;

        alpha = floor(alpha);

        alpha /= beta;

        return alpha;
}

void Mathematic::Unproject(
    Vector3d& Origin,
    Vector3d& Direction,
    const Vector3d& Position2D,
    const Matrix4d& ViewInverse,
    const Matrix4d& Projection,
    int ScreenWidth,
    int ScreenHeight)
{
    // Vector3d of ray in screen space
    Vector3d V;
    V.setX(((((2.0f
               * Position2D.x()))
               / ScreenWidth)
               - 1.0f)
               / Projection.row(1).x());

    V.setY(-((((2.0f
                * Position2D.y()))
                / ScreenHeight)
                - 1.0f)
                / Projection.row(2).y());

    V.setZ(1.0f);

    // transform screen space ray into 3D space
    Direction.setX(V.x() * ViewInverse.column(1).x()
                   + V.y() * ViewInverse.column(1).y()
                   + V.z() * ViewInverse.column(1).z());

    Direction.setY(V.x() * ViewInverse.column(2).x()
                   + V.y() * ViewInverse.column(2).y()
                   + V.z() * ViewInverse.column(2).z());

    Direction.setZ(V.x() * ViewInverse.column(3).x()
                   + V.y() * ViewInverse.column(3).y()
                   + V.z() * ViewInverse.column(3).z());

    Direction.normalize();

    Origin.setX(ViewInverse.row(4).x());
    Origin.setY(ViewInverse.row(4).y());
    Origin.setZ(ViewInverse.row(4).z());
}

Quelqu'un à un indice ?

Je rappelle que j'utilise QtCreator 2 comme IDE.

J'ai aussi une telle erreur à un autre endroit, mais qui demandait de poster plus de code... Je me dis qu'à deux problèmes identiques suffit une seule solution wink.

EDIT : Je post aussi l'autre lieu de même erreur:

Voici angle.h

#include "mathematic.h"
#include "constantes.h"

class Degree;
class Angle;

class Radian
{
public:
    inline                  Radian      (const Degree& a);
    inline                  Radian      (const float a);
    inline                  Radian      (const Radian& r);

    inline Radian&          operator=   (const float& f);
    inline Radian&          operator=   (const Radian& r);
    inline Radian&          operator=   (const Degree& d);

    inline float            valueDegrees() const;
    inline float            valueRadians() const;

    inline static Degree RadianToDegree (const Radian RadAngle);

    inline const Radian&    operator +  () const;
    inline Radian           operator +  (const Radian& r ) const;
    inline Radian           operator +  (const Degree& d ) const;
    inline Radian&          operator += (const Radian& r );
    inline Radian&          operator += (const Degree& d );
    inline Radian           operator -  () const;
    inline Radian           operator -  (const Radian& r ) const;
    inline Radian           operator -  (const Degree& d ) const;
    inline Radian&          operator -= ( const Radian& r );
    inline Radian&          operator -= ( const Degree& d );
    inline Radian           operator *  (const float f ) const;
    inline Radian           operator *  (const Radian& f ) const;
    inline Radian&          operator *= (const float f );
    inline Radian           operator /  (const float f ) const;
    inline Radian&          operator /= (const float f );

    inline bool             operator <  ( const Radian& r ) const;
    inline bool             operator <= ( const Radian& r ) const;
    inline bool             operator == ( const Radian& r ) const;
    inline bool             operator != ( const Radian& r ) const;
    inline bool             operator >= ( const Radian& r ) const;
    inline bool             operator >  ( const Radian& r ) const;

private:
            float           m_rad;

};

class Degree
{
public:
    inline                  Degree (const  float d=0);
    inline                  Degree ( const Radian& r );
    inline                  Degree ( const Degree& d );
    inline Degree&          operator = ( const float& f );
    inline Degree&          operator = ( const Degree& d );
    inline Degree&          operator = ( const Radian& r );

    inline float            valueDegrees() const;
    inline float            valueRadians() const;

    inline static Radian    DegreeToRadian(const Degree DegAngle);

    inline const Degree&    operator + () const;
    inline Degree           operator + ( const Degree& d ) const;
    inline Degree           operator + ( const Radian& r ) const;
    inline Degree&          operator += ( const Degree& d );
    inline Degree&          operator += ( const Radian& r );
    inline Degree           operator - () const;
    inline Degree           operator - ( const Degree& d ) const;
    inline Degree           operator - ( const Radian& r ) const;
    inline Degree&          operator -= ( const Degree& d );
    inline Degree&          operator -= ( const Radian& r );
    inline Degree           operator * ( float f ) const;
    inline Degree           operator * ( const Degree& f ) const;
    inline Degree&          operator *= ( float f );
    inline Degree           operator / ( float f ) const;
    inline Degree&          operator /= ( float f );

    inline bool             operator <  ( const Degree& d ) const;
    inline bool             operator <= ( const Degree& d ) const;
    inline bool             operator == ( const Degree& d ) const;
    inline bool             operator != ( const Degree& d ) const;
    inline bool             operator >= ( const Degree& d ) const;
    inline bool             operator >  ( const Degree& d ) const;

private:
            float            m_deg;
};

class Angle
{
public:
    inline                  Angle(const float angle);
    inline                  Angle(const Angle &a);
    inline                  Angle(const Radian &r);
    inline                  Angle(const Degree &d);
    inline float            angle()const {return m_angle;}
    inline Radian           radian() const;
    inline Degree           degree() const;

    enum                    UniteAngle {DEGREE, RADIAN};

    inline UniteAngle       uniteAngle()const {return m_uniteAngle;}
    inline void             setUniteAngle(const UniteAngle u){m_uniteAngle = u;}

    inline void             set(const Degree &d);
    inline void             set(const Radian &r);
    inline void             set(const Angle &a);
    inline void             set(const float f);

    inline Radian           AngleToRadian()const;
    inline Degree           AngleToDegree()const;

private:
    static UniteAngle       m_uniteAngle;

            float           m_angle;
};

voici ses définitions (angle.cpp)

#include "angle.h"

// RADIAN **********************************************************************
inline Radian::Radian(const Degree& d) : m_rad(d.valueRadians())
{
}
inline Radian::Radian(const float a) : m_rad(a)
{
}
inline Radian::Radian(const Radian& r) : m_rad(r.valueRadians())
{
}

inline Radian& Radian::operator= (const float& f)
{
    m_rad = f; return *this;
}
inline Radian& Radian::operator= (const Radian& r)
{
    m_rad = r.valueRadians(); return *this;
}
inline Radian& Radian::operator= ( const Degree& d )
{
    m_rad = d.valueRadians(); return *this;
}

inline float Radian::valueDegrees() const
{
    return RadianToDegree(m_rad).valueDegrees();
}
inline float Radian::valueRadians() const { return m_rad; }

inline Degree Radian::RadianToDegree(const Radian RadAngle)
{
    return (Degree(RadAngle * RAD2DEG));
}


inline const Radian& Radian::operator + () const 
{ 
  return *this; 
}
inline Radian Radian::operator + ( const Radian& r ) const
{
  return Radian ( m_rad + r.m_rad );
}
inline Radian Radian::operator + ( const Degree& d ) const
{
    return Radian ( m_rad + d.valueRadians());
}
inline Radian& Radian::operator += ( const Radian& r )
{
  m_rad += r.m_rad;
  return *this;
}
inline Radian& Radian::operator += ( const Degree& d )
{
    m_rad += d.valueRadians();
    return *this;
}
inline Radian Radian::operator - () const 
{ 
  return Radian(-m_rad); 
}
inline Radian Radian::operator - ( const Radian& r ) const
{
  return Radian ( m_rad - r.m_rad );
}
inline Radian Radian::operator - ( const Degree& d ) const
{
    return Radian ( m_rad - d.valueRadians() );
}
inline Radian& Radian::operator -= ( const Radian& r )
{
  m_rad -= r.m_rad; return *this;
}
inline Radian& Radian::operator -= ( const Degree& d )
{
    m_rad -= d.valueRadians();
    return *this;
}

inline Radian Radian::operator * ( const float f ) const
{
  return Radian(m_rad * f);
}
inline Radian Radian::operator * ( const Radian& f ) const
{
  return Radian ( m_rad * f.m_rad );
}
inline Radian& Radian::operator *= (const float f )
{
    m_rad *= f; return *this;
}
inline Radian Radian::operator / ( float f ) const
{
  return Radian ( m_rad / f );
}
inline Radian& Radian::operator /= ( float f )
{
  m_rad /= f; return *this;
}

inline bool Radian::operator <  ( const Radian& r ) const
{
  return m_rad <  r.m_rad;
}
inline bool Radian::operator <= ( const Radian& r ) const
{
  return m_rad <= r.m_rad;
}
inline bool Radian::operator == ( const Radian& r ) const
{
  return m_rad == r.m_rad;
}
inline bool Radian::operator != ( const Radian& r ) const
{
  return m_rad != r.m_rad;
}
inline bool Radian::operator >= ( const Radian& r ) const
{
  return m_rad >= r.m_rad;
}
inline bool Radian::operator >  ( const Radian& r ) const
{
  return m_rad >  r.m_rad;
}
// FIN RADIAN ******************************************************************

// DEGREE **********************************************************************
inline Degree::Degree ( float d) : m_deg(d) {}
inline Degree::Degree ( const Radian& r ) : m_deg(r.valueDegrees()) {}
inline Degree::Degree (const Degree& d): m_deg(d.valueDegrees()){}

inline Degree& Degree::operator = ( const float& f )
{
  m_deg = f;
  return *this;
}
inline Degree& Degree::operator = ( const Degree& d )
{
  m_deg = d.m_deg;
  return *this;
}
inline Degree& Degree::operator = ( const Radian& r )
{
  m_deg = r.valueDegrees();
  return *this;
}

inline float Degree::valueDegrees() const { return m_deg; }
inline float Degree::valueRadians() const
{
    return DegreeToRadian(m_deg).valueRadians();
}

inline Radian Degree::DegreeToRadian(const Degree DegAngle)
{
    return(Radian(DegAngle * DEG2RAD));
}

inline const Degree& Degree::operator + () const { return *this; }
inline Degree Degree::operator + ( const Degree& d ) const
{
  return Degree ( m_deg + d.m_deg );
}
inline Degree Degree::operator + ( const Radian& r ) const
{
  return Degree ( m_deg + r.valueDegrees() );
}
inline Degree& Degree::operator += ( const Degree& d )
{
  m_deg += d.m_deg;
  return *this;
}
inline Degree& Degree::operator += ( const Radian& r )
{
  m_deg += r.valueDegrees();
  return *this;
}
inline Degree Degree::operator - () const { return Degree(-m_deg); }
inline Degree Degree::operator - ( const Degree& d ) const
{
  return Degree ( m_deg - d.m_deg );
}
inline Degree Degree::operator - ( const Radian& r ) const
{
  return Degree ( m_deg - r.valueDegrees() );
}
inline Degree& Degree::operator -= ( const Degree& d )
{
  m_deg -= d.m_deg;
  return *this;
}
inline Degree& Degree::operator -= ( const Radian& r )
{
  m_deg -= r.valueDegrees();
  return *this;
}
inline Degree Degree::operator * ( float f ) const
{
  return Degree ( m_deg * f );
}
inline Degree Degree::operator * ( const Degree& f ) const
{
  return Degree ( m_deg * f.m_deg );
}
inline Degree& Degree::operator *= ( float f ) { m_deg *= f; return *this; }
inline Degree Degree::operator / ( float f ) const
{
  return Degree ( m_deg / f );
}
inline Degree& Degree::operator /= ( float f ) { m_deg /= f; return *this; }

inline bool Degree::operator <  ( const Degree& d ) const
{
  return m_deg <  d.m_deg;
}
inline bool Degree::operator <= ( const Degree& d ) const
{
  return m_deg <= d.m_deg;
}
inline bool Degree::operator == ( const Degree& d ) const
{
  return m_deg == d.m_deg;
}
inline bool Degree::operator != ( const Degree& d ) const
{
  return m_deg != d.m_deg;
}
inline bool Degree::operator >= ( const Degree& d ) const
{
  return m_deg >= d.m_deg;
}
inline bool Degree::operator >  ( const Degree& d ) const
{
  return m_deg >  d.m_deg;
}
// FIN DEGREE ******************************************************************

// ANGLE **********************************************************************
inline Angle::Angle(const float angle):m_angle(angle){}
inline Angle::Angle(const Angle &a):m_angle(a.angle()){}
inline Angle::Angle(const Radian &r)
{
    if (uniteAngle() == DEGREE)
        m_angle = r.valueDegrees();
    else if (uniteAngle() == RADIAN)
        m_angle = r.valueRadians();
    else
        return;
}
inline Angle::Angle(const Degree &d)
{
    if (uniteAngle() == DEGREE)
        m_angle = d.valueDegrees();
    else if (uniteAngle() == RADIAN)
        m_angle = d.valueRadians();
    else
        return;
}
inline Radian Angle::radian() const
{
    return AngleToRadian();
}
inline Degree Angle::degree() const
{
    return AngleToDegree();
}
inline Radian Angle::AngleToRadian() const
{
    if (uniteAngle() == RADIAN)
        return (Radian(angle()));
    if (uniteAngle() == DEGREE)
        return Mathematic::DegreeToRadian(Degree(angle()));
    else return Radian(0);
}
inline Degree Angle::AngleToDegree() const
{
    if (uniteAngle() == DEGREE)
        return (Degree(angle()));
    if (uniteAngle() == RADIAN)
        return Mathematic::RadianToDegree(Radian(angle()));
    else return Degree(0);
}

inline void Angle::set(const Degree &d)
{
    set(Angle(d));
}
inline void Angle::set(const Radian &r)
{
    set(Angle(r));
}
inline void Angle::set(const Angle &a)
{
    m_angle = a.angle();
}
inline void Angle::set(const float f)
{
    set(Angle(f));
}

// FIN ANGLE *******************************************************************

Et finalement voici le lieu des erreurs, dans la définition de la classe Vector3d (vector3d.cpp), annoté avec les lieu spécifiques des erreurs.
Il y a des fonctions ici qui ne sont pas définies (qui me donnent des warnings) mais aucune référence à ces fonctions n'est faite nulle part.

#include "MATHvector3d.h"

Vector3d::Vector3d():QVector3D()
{
}
Vector3d::Vector3d(const float x, const float y, const float z):QVector3D(x,y,z)
{

}
Vector3d::Vector3d(const float array[3]):QVector3D(array[0],array[1],array[2])
{
}
Vector3d::Vector3d(const int array[3]):QVector3D(array[0], array[1], array[2])
{
}
Vector3d::Vector3d(const float s):QVector3D(s,s,s)
{
}
Vector3d::Vector3d(const QPoint &point):QVector3D(point)
{

}
Vector3d::Vector3d(const QPointF &point):QVector3D(point)
{

}
Vector3d::Vector3d(const QVector2D &v):QVector3D(v)
{

}
Vector3d::Vector3d(const QVector2D &vector, const float z):QVector3D(vector, z)
{

}
Vector3d::Vector3d(const QVector3D &v):QVector3D(v.x(),v.y(),v.z())
{
}

void Vector3d::set(const float x, const float y, const float z)
{
    setX(x);
    setY(y);
    setZ(z);
}
void Vector3d::set(const QVector3D &v)
{
    setX(v.x());
    setY(v.y());
    setZ(v.z());
}
void Vector3d::reset()
{
    set(0,0,0);
}

float Vector3d::distanceToVec(const QVector3D &v)const
{
    return sqrt(distanceToVecSquared(v));
}
float Vector3d::distanceToVecSquared(const QVector3D &v)const
{
    return (*this - v).lengthSquared();
}
Angle Vector3d::angleBetween(const QVector3D & v)const
{
    float produitDesNormes = this->length() * v.length();

    // Prévention de la division par zéro
    if (produitDesNormes < 1e-6f)
        produitDesNormes = 1e-6f;

    float a = dotProduct(*this,v)/produitDesNormes;

    float b = acos(Mathematic::Clamp(a, 0-1.0f, 1.0f));

    return Angle(Radian(b)); // UNDEFINED REFERENCE TO 'Radian::Radian(float)'
                                            // UNDEFINED REFERENCE TO 'Angle::Angle(Radian const&)'
}
Angle Vector3d::angleBetweenXAxis()const
{
//    return angleBetween(AXEX);
}
Angle Vector3d::angleBetweenYAxis()const
{
//    return angleBetween(AXEY);
}
Angle Vector3d::angleBetweenZAxis()const
{
//    return angleBetween(AXEZ);
}
bool Vector3d::isUnit()const
{
    return (lengthSquared() == 1);
}

float* Vector3d::data()const
{
    float array[3] = {x(), y(), z()};
    return array;
}
Vector3d& Vector3d::projectionSurLigne(const QVector3D& v)
{
 //FAUX
}
Vector3d& Vector3d::projectionSurPlan(const QVector3D p1, const QVector3D p2)
{

}

void Vector3d::operator=(const Vector3d & v)
{
    set(v);
}

Vector3d Vector3d::fuzz(const float amp)
{
    Vector3d v(x() + (Mathematic::Random() * (amp * 2) - amp),   // UNDEFINED REFERENCE TO 'Mathematic::Random()'
            y() + (Mathematic::Random() * (amp * 2) - amp),            // UNDEFINED REFERENCE TO 'Mathematic::Random()'
            z() + (Mathematic::Random() * (amp * 2) - amp));           // UNDEFINED REFERENCE TO 'Mathematic::Random()'
    return v;
}

Merci d'avance !

Dernière modification par Maneithel (Le 15/03/2011, à 23:49)

Hors ligne

#2 Le 15/03/2011, à 20:53

omc

Re : [RÉSOLU]QtCreator, Qt, C++ Étrange undefined reference to 'function()'

bonjour,
il faut enlever le mot clé inline

Hors ligne

#3 Le 15/03/2011, à 21:08

Maneithel

Re : [RÉSOLU]QtCreator, Qt, C++ Étrange undefined reference to 'function()'

Bonjour !
J'ai fait rapidement le test (j'approfondis ce soir) et en effet, ça marche.
Savez vous pourquoi ?

Je reviens avec plus de résultat d'ici quelques heures.

Hors ligne

#4 Le 15/03/2011, à 23:48

Maneithel

Re : [RÉSOLU]QtCreator, Qt, C++ Étrange undefined reference to 'function()'

Cela fonctionne en effet, et si quelqu'un a une explication, je suis partant !
J'ai un autre probleme, mais ça ira dans une autre discution.

Hors ligne

#5 Le 17/03/2011, à 14:28

omc

Re : [RÉSOLU]QtCreator, Qt, C++ Étrange undefined reference to 'function()'

Hors ligne

#6 Le 17/03/2011, à 17:34

Maneithel

Re : [RÉSOLU]QtCreator, Qt, C++ Étrange undefined reference to 'function()'

Merci, excellent lien.

Hors ligne