J'ai essayé d'utiliser ce code dans VS2008 (et peut-être inclus trop contexte dans l'échantillon ...):Hériter d'un paramètre de modèle et transtypage ascendant retour en C++
class Base
{
public:
void Prepare() {
Init();
CreateSelectStatement();
// then open a recordset
}
void GetNext() { /* retrieve next record */ }
private:
virtual void Init() = 0;
virtual string CreateSelectStatement() const = 0;
};
class A : public Base
{
public:
int foo() { return 1; }
private:
virtual void Init() { /* init logic */ }
virtual string CreateSelectStatement() { /* return well formed query */ }
};
template<typename T> class SomeValueReader : protected T
{
public:
void Prepare() { T::Prepare(); }
void GetNext() { T::GetNext(); }
T& Current() { return *this; } // <<<<<<<< this is where it is interesting
SomeValue Value() { /* retrieve values from the join tables */ }
private :
string CreateSelectStatement() const
{
// special left join selection added to T statement
}
};
void reader_accessAmemberfunctions_unittest(...)
{
SomeValueReader<A> reader();
reader.Prepare();
reader.GetNext();
A a = reader.Current();
int fooresult = a.foo();
// reader.foo() >> ok, not allowed
Assert::IsEqual<int>(1, fooresult);
};
Cela fonctionne comme prévu, dire ayant accès à « a » fonctions membres et fooresult de retour 1. Toutefois, une exception est levée lorsque les objets sont supprimés à la fin de la fonction unittest:
System.AccessViolationException: tentative pour lire ou écrire protégé Mémoire. Cela est souvent une indication qu'une autre mémoire est corrompue
Si je change le type de retour de la fonction() à:
T* Current()
{
T* current = dynamic_cast<T*>(this);
return current;
}
alors tout est ok et la fin de test unitaire sans violation d'accès . Quelqu'un peut-il me dire ce qui n'allait pas avec la première implémentation Current()? Merci, bouchaet.
Je suis surpris que tout code soit généré "à la fin de la fonction unittest". Il semble qu'aucun de ces objets n'a de destructeur. –
Vous avez ici suffisamment de code pour le coller dans un nouveau projet, renommer la fonction unittest en 'main()', et reproduire le problème de zéro. J'essaierais ça. –