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 09/02/2011, à 15:07

no_spleen

[résolu][c++] problème de vtable

Bonjour à tous,

Je m'essaye aux joyeusetés du c++, et je tombe sur un os. Je crée une classe de base comme ceci :

FEM_BASE.h

template<class T>
class FEM_BASE
{
protected :
    GModel *gm;
public :
    FEM_BASE (GModel *_gm) :  gm(_gm) {};
    void numbering(int physical,
                   int dimOfPhysical,
                   int icomp,
                   int iField,
                   Assembler<T> &assem,
                   bool isEnriched = false);
    void solve(linearSystem<T> &lsys);
    PView* getSolution(Assembler<T> &assem,std::string name, int icomp,int ifield,double time);
    virtual void setParameters(std::vector<T> par) = 0;
    virtual void build(Assembler<T> &lsys, int icomp, int ifield) = 0;
};

qui contient donc 2 fonctions virtuelles pures. Je définis les autres dans le fichier FEM_BASE.cpp

#include "FEM_BASE.h"

template<class T> void FEM_BASE<T>::numbering (int dimOfPhysical, 
                          int physical, 
                          int iComp, 
                          int iField, 
                          Assembler<T> &assem,
                          bool enriched)
{
    
    std::vector<MVertex *> v;
    gm->getMeshVerticesForPhysicalGroup(dimOfPhysical,physical,v);
    for (unsigned int i=0;i<v.size();i++){
        assem.numberVertex (v[i], iComp, iField);    
    }  
}

template<class T> void FEM_BASE<T>::solve (linearSystem<T> &lsys)
{
    lsys->systemSolve(); 
}

template<class T> PView* FEM_BASE<T>::getSolution(Assembler<T> &assem, 
                                                  std::string name,
                                                  int icomp, 
                                                  int ifield,
                                                  double time)
{
    std::vector<GEntity*> entities;
    gm->getEntities(entities);
    std::map<int, std::vector<double> > d;
    for(unsigned int i = 0; i < entities.size(); i++){
        for(unsigned int j = 0; j < entities[i]->getNumMeshVertices(); j++){
            MVertex *v = entities[i]->getMeshVertex(j);
            d[v->getNum()].push_back(assem.getDofValue(v,icomp,ifield));
        }
    }
    PView *p = new PView(name,"NodeData",gm,d,time,ifield);
    return p;
}

Fort de cette belle classe de base, je veux en hériter une, qui défini les deux fonctions virtuelles pures. Je m'y attelle donc en écrivant ce BS_EUROPEAN.h

template<class T>
class BS_European : public FEM_BASE<T>
{
protected :
    GModel *gm;
    double vol;
    double r;
    double dt;
public :
    BS_European (GModel *_gm) : FEM_BASE<T>(_gm) , gm(_gm) {};    
    void setParameters(std::vector<T> par);
    void build(Assembler<T> &lsys, int icomp, int ifield);
};

et je défini ces fameuses fonctions dans BS_EUPEAN.cpp

template<class T> void BS_European<T>::setParameters(std::vector<T> par)
{
    vol(par[0]);
    r(par[1]);
    dt(par[2]);
};

template<class T> void BS_European<T>::build(Assembler<T> &lsys, int icomp, int ifield)
{
    // create matrix blocks
    Mass_Block<T>       mass(gm);
    Stiffness_Block<T>  stiff(gm);
    Mixed_Block<T>      mixed(gm);
    Source_Block<T>     source(gm);

    std::vector<GEntity*> entities;
    gm->getEntities(entities);

    for(unsigned int i = 0; i < entities.size(); i++){
        for(unsigned int j = 0; j < entities[i]->getNumMeshVertices(); j++){
            MVertex *v = entities[i]->getMeshVertex(j);
            double val = 1.0/dt - r;
            lsys.parVertex(v,icomp,ifield,val);
        }
    }
    
    mass.build(lsys,icomp,ifield);

    for(unsigned int i = 0; i < entities.size(); i++){
        for(unsigned int j = 0; j < entities[i]->getNumMeshVertices(); j++){
            MVertex *v = entities[i]->getMeshVertex(j);
            double val = -0.5 * vol * vol * v->x() * v->x();
            lsys.parVertex(v,icomp,ifield,val);
        }
    }
    
    stiff.build(lsys,icomp,ifield);

    for(unsigned int i = 0; i < entities.size(); i++){
        for(unsigned int j = 0; j < entities[i]->getNumMeshVertices(); j++){
            MVertex *v = entities[i]->getMeshVertex(j);
            double val = r * v->x() ;
            lsys.parVertex(v,icomp,ifield,val);
        }
    }
    mixed.build(lsys,icomp,ifield);

    for(unsigned int i = 0; i < entities.size(); i++){
        for(unsigned int j = 0; j < entities[i]->getNumMeshVertices(); j++){
            MVertex *v = entities[i]->getMeshVertex(j);
            double val = 1.0 / dt;
            lsys.parVertex(v,icomp,ifield,val);
        }
    }
    source.build(lsys,icomp,ifield);
};

Une fois tout ceci fait, je veux utiliser ma classe BS_European, et lui appliquer les méthodes numbering, build et setParameters. Hors lors de la compilation j'ai ce message d'erreur

"FEM_BASE<double>::numbering(int, int, int, int, Assembler<double>&, bool)", referenced from:
      _main in main.o
  "BS_European<double>::build(Assembler<double>&, int, int)", referenced from:
      _main in main.o
      vtable for BS_European<double>in main.o
  "BS_European<double>::setParameters(std::vector<double, std::allocator<double> >)", referenced from:
      _main in main.o
      vtable for BS_European<double>in main.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

Est-ce que l'un d'entre vous pourrais me dire la ou j'ai péché ?

Un grand merci

Dernière modification par no_spleen (Le 10/02/2011, à 13:53)

Hors ligne

#2 Le 09/02/2011, à 16:52

Luc Hermitte

Re : [résolu][c++] problème de vtable

Les templates ont un modèle de link très particulier.
Je t'invite à consulter la FAQ C++ de dvpz.
(en résumé => mets tout dans le .h)

Hors ligne

#3 Le 10/02/2011, à 13:52

no_spleen

Re : [résolu][c++] problème de vtable

Un grand merci ! Y-a-t-il une raison particulière à ce comportement ?

Hors ligne

#4 Le 10/02/2011, à 15:37

Luc Hermitte

Re : [résolu][c++] problème de vtable

Ben ... parce qu'il s'agit de templates ...
C'est du code remplacé au dernier moment lors de la compilation. Il est donc nécessaire partout où il est utilisé.
Tout simplement.

Autre lecture par là: http://www.comeaucomputing.com/techtalk … es/#export

Hors ligne