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