probleme avec les templates et heritage

Le
thierry nivon
Bonjour,
j'ai un problème avec une utilisation des templates dans le header suivant.
En fait il s'agit en fin de header des instructions

NeedLockúlse ;
Splitter=new TSplitter() ;

gcc me retourne
/home/tn/dev-perso/tnutils/trunk/tnutils/src/../include/tnserial.h:190:
erreur: ‘NeedLock’ was not declared in this scope
/home/tn/dev-perso/tnutils/trunk/tnutils/src/../include/tnserial.h:191:
erreur: ‘Splitter’ was not declared in this scope
gmake[2]: *** [include/CMakeFiles/tnserial.dir/tnserial.o] Erreur 1

or ces données sont dans l'ancetre de CSerialPortTdSplitter et même en
public.

Je n'arrie pas à comprendre où est le problème.

Si qq'un a une piste (voire la solution !)

Thierry

#ifndef _TNSERIAL_H_
#define _TNSERIAL_H_

#include <tnpthread.h>
#include <SerialPort.h>
#include <list>


class CSerialPortSplitter ;

/** @brief extends SerialPort by adding to it threaded reading.

A thread will read data from com port and put it in buffer.
It can also have a parser wich will create chars segment
corresponding to a message

*/
class CSerialPortTdBas : public SerialPort
{
private:
typedef SerialPort _ancestor_ ;
typedef std::list<char *> TSplitList ;

CSerialPortTdBas(const CSerialPortTdBas &) ;
const CSerialPortTdBas &operator=(const CSerialPortTdBas&) ;

typedef pthd::CPEmbeddedThread<CSerialPortTdBas> TSerialThread ;
TSerialThread *SerialThread ;

protected:
char *InputBuffer ;
int InputBufferSize ,
InputBufferCount ;
TSplitList SplitList ;

pthread_mutex_t *BuffMutex ;

//! In case of too many frame waiting to be read drop the oldest one
void DropFirstFrame() { free(GetFrame()) ; }


public:
CSerialPortTdBas(std::string &_SerialPort) ;
virtual ~CSerialPortTdBas() ;

// Pour l'instant ici
//! @todo revoir les templates
CSerialPortSplitter *Splitter ;
bool NeedLock ;

int ExecuteThread(pthd::CPThread *Thread) ;

/** Default time out when waiting for a char */
int TimeOut ;
/** Max number of frame splitted and waiting to be read. When a new
frame arrive
and the number of waiting frame has reached this number, the
oldest one will be dropped
*/
unsigned int MaxFrameCount ;

/** Start to read the serial port and feeding InputBuffer
*/
void StartSerialRead() ;

void LockData() { pthread_mutex_lock(BuffMutex) ; }
void UnlockData() { pthread_mutex_unlock(BuffMutex) ; }

/** @return the number of accumlated frames in the list
*/
unsigned int FrameCount() const { return SplitList.size() ; }

/** @return return the first frame in the list, and remove it from
the list.
Return NULL if no frame is present in the list
*/
char *GetFrame() ;
} ;


/** @brief A buffer with a defined buffer

This is a usable Serial Port, as its ancestor as no buffer to store
incoming data,
so thread is useless
*/
template <int BuffSize>
class CSerialPortTdBuff : public CSerialPortTdBas
{
private:
typedef CSerialPortTdBas _ancestor_ ;
CSerialPortTdBuff(const CSerialPortTdBuff&) ;
const CSerialPortTdBuff & operator=(const CSerialPortTdBuff&) ;


public:
CSerialPortTdBuff(std::string &_SerialPort) ;
} ;

template <class TSplitter, int BuffSize>
class CSerialPortTdSplitter : public CSerialPortTdBuff<BuffSize>
{
private:
typedef CSerialPortTdBuff<BuffSize> _ancestor_ ;

CSerialPortTdSplitter(const CSerialPortTdSplitter&) ;
const CSerialPortTdSplitter &operator=(const CSerialPortTdSplitter&) ;

public:
CSerialPortTdSplitter(std::string &_SerialPort) ;

} ;

/** @brief The basic splitter

Try to find a frame in a buffer. There is several manner to split a
frame :
- Identified beginning and end chars
- Only end chars (CR or LF, or CRLF, by example)
- Only a start char, and fixed length
-

When trying to split several case can be found :
- we find the beginning of a frame, but not the end --> To not
overflow the buffer it can be right to
move the beginning of the from on the beginning of the buffer, to
make place of the rest of incoming frame -->
We would return @em saClearUntilBeg and SplitStart to the position
of the beginning of frame, or @em saNothing
if the beginning of the frame is already at the fist position in buffer.
- We can not find no frame start --> We could return @em saClearAll
- We find a frame --> we must return @em saMakeSplit with SplitStart
and SplitEnd on the start and end of frame
-

*/
class CSerialPortSplitter
{
private:
CSerialPortSplitter(const CSerialPortSplitter&) ;
const CSerialPortSplitter &operator=(const CSerialPortSplitter&) ;

public:
CSerialPortSplitter() ;
virtual ~CSerialPortSplitter() ;

//! The action to do after splitting
enum ESplitAction {
saNothing, //!< Nothing to do
saClearUntilBeg, //!< A beginning of frame has
been found, so we must clear until beginning
saClearAll, //!< Nothing found in the buffer, so
clear all
saMakeSplit //!< A frame has been found, so we
extract it and put it in the split list
} ;


/** Try to find a frame in the buffer, and return what action to do
after analyzis
* @param _Buffer The buffer where to search a frame
* @param _BufferCount the buffer length
* @param SplitStart the beginning of the frame.
* @param SplitEnd the end of the frame
* @return The action to do.
*/
virtual ESplitAction Split(const char *_Buffer, const int
_BufferCount, int *SplitStart, int *SplitEnd) = 0 ;

} ;

template <int BuffSize>
CSerialPortTdBuff<BuffSize>::CSerialPortTdBuff(std::string &_SerialPort) :
_ancestor_(_SerialPort)
{
InputBuffer=(char *) malloc(BuffSize) ;
InputBufferSize=BuffSize ;
}

template <class TSplitter, int BuffSize>
CSerialPortTdSplitter<TSplitter,
BuffSize>::CSerialPortTdSplitter(std::string &_SerialPort) :
_ancestor_(_SerialPort)
{
NeedLockúlse ;
// CSerialPortTdBas::Splitter=new TSplitter() ;
}

#endif // _TNSERIAL_H_
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Franck Branjonneau
Le #313095
(Pour une prochaine fois : réduit ton code à un minimum compilable -- modulo
l'erreur)

thierry nivon
j'ai un problème avec une utilisation des templates dans le header suivant.
Je n'arrie pas à comprendre où est le problème.

Si qq'un a une piste (voire la solution !)


Tu as *en résumé* une classe template B qui hérite d'une classe template A et
qui tente dans une fonction membre B::foo d'accéder à un membre de A.

template< int >
struct A:

int member_;
};

template< int i >
struct B:
public A< i > {

int
foo() {
return member_;
}
} ;

Le problème est que dans B::foo, le symbole member_ n'est pas dépendant. Il
est donc cherché dans la premier temps de la compilation du template. En
particulier le compilateur ne le cherche pas dans la classe template hérité
A< i >.

La solution est de rendre member_ dépendant :

int
foo() {
return A< i >::member_;
}

ou (je crois que c'est la solution la plus prisée)

int
foo() {
return this->member_;
}


ou enfin en utilisant une « using déclaration » (de préférence au niveau de la
classe)

template< int i >
struct B:
public A< i > {

using A< i >::member_;

int
foo() {
return member_;
}
} ;

Toutes ont des avantages et des inconvénients.

--
Boujou
Franck

Publicité
Poster une réponse
Anonyme