Pages : 1
#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