J'ai un BaseClass
et certaines classes dérivées
#ifndef TEST_H__
#define TEST_H__
#include <iostream>
#include <memory>
class BaseClass
{
public:
virtual double eval(double x) const = 0;
};
class Square: public BaseClass
{
public:
double eval(double x) const {return x*x;}
};
class Add1: public BaseClass
{
public:
Add1(BaseClass & obj): obj_(obj) {}
double eval(double x) const {return obj_.eval(x) + 1.0;}
private:
BaseClass & obj_;
};
#endif /* TEST_H__ */
qui sont traitées avec SWIG à la
%module test
%{
#define SWIG_FILE_WITH_INIT
%}
%{
#include "test.h"
%}
%include "test.h"
Ceci peut être utilisé à partir de Python comme
import test
s = test.Square()
a = test.Add1(s)
print(a.eval(2.0))
Qu'est-ce que Par défaut :
import test
a = test.Add1(test.Square())
print(a.eval(2.0))
Pourquoi ? Le site test.Square()
n'est pas assigné à une variable, donc n'existe plus après l'assignation à a
y obj_
pointe vers un stockage invalide.
Pour éviter un tel comportement, l'idée est d'utiliser std::shared_ptr<BaseClass>
au lieu de BaseClass&
c'est-à-dire
class Add1: public BaseClass
{
public:
Add1(std::shared_ptr<BaseClass> & obj): obj_(obj) {}
double eval(double x) const {return obj_->eval(x) + 1.0;}
private:
std::shared_ptr<BaseClass> obj_;
};
Ce code exact ne fonctionnera pas cependant avec
TypeError: in method 'new_Add1', argument 1 of type 'std::shared_ptr< BaseClass > &'
C'est logique, aussi : test.Square()
ne renvoie pas un std::shared_ptr<BaseClass>
mais simplement un Square
alias BaseClass
instance.
Est-il possible d'avoir test.Square()
retourne un pointeur partagé std::shared_ptr<Square>
?