OVH Cloud OVH Cloud

VC++6: method virtuelle de class parent non accessible.

4 réponses
Avatar
fpicca at ltpcm inpg fr
Bonjour

je ne mets pas les constructeurs et destructeurs.

namespace toto {
class Parent
{
public:
virtual void method(void);
}
namespace titi {
class Fille : public Parent
{
public
virtual void method(void);
}
}

lorsque j'impl=E9mente la classe fille:
void Fille::method(void)
{
typedef toto::Parent ParentName;
ParentName::method(void);
}

Je suis oblig=E9 de passer par un typedef du fait d'un bug de VC++6 qui
ne reconnait pas l'=E9criture
toto::Parent::method();

Le probl=E8me est que lors de l'execution de Fille::method(), la
m=E9thode parent n'est pas appel=E8e mais c'est elle m=EAme qui s'app=E8le
de fa=E7on r=E9cursive.
Fille -> Fille -> Fille ...
=E0 la place de=20
Fille -> Parent

Qu'es-je donc fais de mal ? ;)

4 réponses

Avatar
Aurelien Regat-Barrel
Bonjour


Bonjour,

Je suis obligé de passer par un typedef du fait d'un bug de VC++6 qui
ne reconnait pas l'écriture
toto::Parent::method();


et Parent::method() ?

Le problème est que lors de l'execution de Fille::method(), la
méthode parent n'est pas appelèe mais c'est elle même qui s'appèle
de façon récursive.
Fille -> Fille -> Fille ...
à la place de
Fille -> Parent

Qu'es-je donc fais de mal ? ;)


Si tu es sûr de ton code (et donc du bug de VC++), tu peux essayer ce
que ça donne avec le mot-clé spécifique __super:

__super::method();

si ça résoud le problème, ce mot-clé est facile à rendre portable:

#ifndef _MSC_VER
typedef toto::Parent __super;
#endif
__super::method();


--
Aurélien Regat-Barrel

Avatar
fpicca at ltpcm inpg fr
et Parent::method() ?


Le problème c'est que ma class parent et ma class fille ont toutes les
deux le même nom mais sont dans deux namespaces différents.

donc je ne peux pas utiliser Parent::method();

Si tu es sûr de ton code (et donc du bug de VC++), tu peux essayer ce
que ça donne avec le mot-clé spécifique __super:


Oui je suis sur du bug:
http://support.microsoft.com/default.aspx?scid=kb%3Bfr%3B153801

__super::method();


pour ce qui est de __super le compilateur me dit qu'il ne connaît pas
ce mot.
Faut-il inclure un header spéciale ?



si ça résoud le problème, ce mot-clé est facile à rendre portab le:

#ifndef _MSC_VER
typedef toto::Parent __super;
#endif
__super::method();


Cela me semble-t-il est équivalent à ce que microsoft préconise:
typedef toto:Parent BaseName;
BaseName::method();



--
Aurélien Regat-Barrel


Avatar
Aurelien Regat-Barrel
et Parent::method() ?



Le problème c'est que ma class parent et ma class fille ont toutes les
deux le même nom mais sont dans deux namespaces différents.

donc je ne peux pas utiliser Parent::method();


Si tu es sûr de ton code (et donc du bug de VC++), tu peux essayer ce
que ça donne avec le mot-clé spécifique __super:



Oui je suis sur du bug:
http://support.microsoft.com/default.aspx?scid=kb%3Bfr%3B153801


Ce bug porte sur les nested classes, tu utilises des namespaces.
Etait-ce pour l'exemple ?
Par sûr de ton code, je voulais dire sûr du programme de test, qu'il n'y
a pas une bête erreur genre Fille::methode est implémentée dans le
mauvais namespace ce qui fait qu'il s'agit de Parent::methode() (si
Fille et Parent ont le même nom). As-tu testé avec un autre compilo ?
A défaut peux-tu poster un petit bout de code proche de ton cas qui
reproduit le problème ?

__super::method();



pour ce qui est de __super le compilateur me dit qu'il ne connaît pas
ce mot.
Faut-il inclure un header spéciale ?


J'ai vérifié trop vite : __super a été introduit après VC++ 6 semble-t-il.

si ça résoud le problème, ce mot-clé est facile à rendre portable:

#ifndef _MSC_VER
typedef toto::Parent __super;
#endif
__super::method();



Cela me semble-t-il est équivalent à ce que microsoft préconise:
typedef toto:Parent BaseName;
BaseName::method();


note le ifndef et non pas ifdef, qui fait que le typedef n'est justement
pas utilisé avec VC++.

--
Aurélien Regat-Barrel


Avatar
fpicca at ltpcm inpg fr
Ce bug porte sur les nested classes, tu utilises des namespaces.
Etait-ce pour l'exemple ?


Non pas seulement, ma librairie contient des tas de namespace.


Par sûr de ton code, je voulais dire sûr du programme de test, qu'il n'y
a pas une bête erreur genre Fille::methode est implémentée dans le
mauvais namespace ce qui fait qu'il s'agit de Parent::methode() (si
Fille et Parent ont le même nom). As-tu testé avec un autre compilo ?


Oui ca compile tres bien avec g++4.0.3

le code de ma method computeAngles est le suivant.

#ifdef MSVC6
//bug C2352
typedef hkl::mode::eulerian4C::vertical::Bissector
BaseName;
BaseName::computeAngles(h, k, l, UB,
m_geometry_E4C);
#else

mode::eulerian4C::vertical::Bissector::computeAngles(h, k, l, UB,
m_geometry_E4C);
#endif

Ce bout de code compila avec gcc et VC++6.
C'est juste à l'execution que je vois le différence.

A défaut peux-tu poster un petit bout de code proche de ton cas qui
reproduit le problème ?


-------- mode_eulerian4C.h
#ifndef _MODE_EULERIAN4C_H_
#define _MODE_EULERIAN4C_H_

#include "mode.h"

namespace hkl {
namespace mode {
namespace eulerian4C {

/*!
* This class defines the mode for all the 4 circles
Eulerian diffractometers.
*/
class Vertical : /*virtual*/ public Mode
{
public:

virtual ~Vertical(void); //!< Default destructor

/*!
* brief The main function to get a sample of angles
from (h,k,l).
* param h The scaterring vector first element.
* param k The scaterring vector second element.
* param l The scaterring vector third element.
* param UB The product of the orientation matrix U by
the crystal matrix B.
* param[out] geometry The Geometry to calculate.
*
* The main function to get a sample of angles from
(h,k,l).
*/
virtual void computeAngles(double h, double k, double l,
smatrix const & UB,
Geometry & geometry) const
throw (HKLException) = 0;

protected:

Vertical(void); //!< Default constructor - protected to
make sure this class is abstract.
};

namespace vertical {

/*!
* The eulerian 4-circle diffractometer in bissector
mode.
*/
class Bissector : public Vertical
{
public:

Bissector(void); //!< Default constructor.

virtual ~Bissector(void); //!< Default Destructor.

virtual void computeAngles(double h, double k, double
l,
smatrix const & UB,
Geometry & geometry) const
throw (HKLException);
};
} // namespace vertical
} // namespace eulerian4C
} // namespace mode
} // namespace hkl

------------------

------------------- mode_kappa4C.h
#ifndef _MODE_KAPPA4C_H_
#define _MODE_KAPPA4C_H_

#include "mode.h"
#include "mode_eulerian4C.h"
#include "geometry_kappa4C.h"
#include "geometry_eulerian4C.h"

namespace hkl {
namespace mode {
namespace kappa4C {
/*!
* This class defines the mode for all the 4 circles Kappa
diffractometers.
*/
class Vertical
{
public:

virtual ~Vertical(void); //!< Default destructor

protected:
mutable geometry::eulerian4C::Vertical m_geometry_E4C;
//!< The geometry::Eulerian4C use for the calculation

Vertical(void); //!< Default constructor - protected to
make sure this class is abstract.
};

namespace vertical {

class Bissector : public
mode::eulerian4C::vertical::Bissector//, public mode::kappa4C::Vertical
{
public:

Bissector(void); //!< Default constructor.

virtual ~Bissector(void); //!< Default Destructor.

virtual void computeAngles(double h, double k, double
l,
smatrix const & UB,
Geometry & geometry) const
throw (HKLException);
protected:
mutable geometry::eulerian4C::Vertical
m_geometry_E4C; //!< The geometry::Eulerian4C use for the calculation
};
} // namespace vertical
} // namespace kappa4C
} // namespace mode
} // namespace hkl
-----------------------

Voila !