[Rcpp-devel] Module with vector of a class with inheritance, how to avoid slicing

Robin Girard robin.girard at mines-paristech.fr
Wed Apr 3 20:07:14 CEST 2013


additional remark : if operator SEXP() ; is added to class father,  children1_t,  and children2_t the solution with XPtr compiles but gives the same result as the solution with shared_ptr (i.e. slicing)
R.


----- Mail original -----
De: "Robin Girard" <robin.girard at mines-paristech.fr>
À: rcpp-devel at lists.r-forge.r-project.org
Cc: "Robin GIRARD" <robin.girard at mines-paristech.fr>
Envoyé: Mercredi 3 Avril 2013 18:43:32
Objet: Module with vector of a class with inheritance, how to avoid slicing

I am still working on my vector of a class father with inheritance (polymorphic subclasses ?). I created an exemple below that works fine but I face the known problem of "slicing" as named here : http://stackoverflow.com/questions/10154977/c-vector-with-inheritance and fail to implement the proposed solution.

I have 2 tried 2 things and ended up with 2 questions: 

Question 1 -  I tryed the solution proposed in the link with make_shared and shared_ptr. I had to add PKG_CXXFLAGS=-g -std=c++0x since my MinGW compiler did not find any -std=c++11.  I got no compilation error but when I run the code it slices my children class : 

> res=new("Rcpp_vector_Of_father")
> res$push_back(new("Rcpp_father"))
> res$push_back_children1_t(new("Rcpp_children1_t"))
> res$WhoAmI(1)
father
> res$WhoAmI(0)
father
> 
> res[[1]]$WhoAmI()
father
> res[[0]]$WhoAmI()
father


Question 2 - I tryed a solution with XPtr (although I'm not sure how this works) and got the following error at the module compilation 
example_mod_consumption.cpp: In member function 'void vector_Of_father::push_back_children1_t(children1_t)':
example_mod_consumption.cpp:80:53: error: no matching function for call to 'std::vector<Rcpp::XPtr<father> >::push_back(Rcpp::XPtr<children1_t>)'


below are the code for the two approach and at the end the code of the module. 



-------------------- Solution with XPtr 

#include <Rcpp.h>

using namespace std;
using namespace Rcpp;

class father ;
class children1_t;
class children2_t ;
class vector_Of_father;

RCPP_EXPOSED_CLASS(father)
RCPP_EXPOSED_CLASS(children1_t)
RCPP_EXPOSED_CLASS(children2_t)
RCPP_EXPOSED_CLASS(vector_Of_father)

class father
{
  public:
    ~father(){};
    father(){};
    father(father const & x) {};
    void WhoAmI() const{
      Rcout<<"father"<<endl;
    };
};

class children1_t : public father
{
  
  public:
    ~children1_t(){};
    children1_t(){};
    children1_t(children1_t const & x){};
    void WhoAmI() const{
      Rcout<<"son1"<<endl;
    };
};

class children2_t : public father
{
  public:
    ~children2_t(){};
    children2_t(){};
    children2_t(children2_t const & x){};
        void WhoAmI() const{
      Rcout<<"son2"<<endl;
    };
};


class vector_Of_father {
  
  public:
    std::vector<XPtr<father> > MyfatherList_;
    //std::vector<shared_ptr<father> > MyfatherList_;
    ~vector_Of_father(){};
    vector_Of_father() : MyfatherList_(){};
	father vec_get( int i) { return(*(MyfatherList_.at(i))); };

	void WhoAmI(int i) const
	{
		MyfatherList_[i]->WhoAmI(); 
	};
	int size(){ return(MyfatherList_.size()); };
 
	void push_back(father func){
		MyfatherList_.push_back(XPtr<father>(&func));
	};
  
	void push_back_children1_t(children1_t func){
		MyfatherList_.push_back(XPtr<children1_t>(&func));
	};
};

-------------------- Solution with make_shared and shared_ptr

only the class vector_of_father is different also #include <memory> is added after Rcpp.h include. 

class vector_Of_father {
  
  public:
    std::vector<shared_ptr<father> > MyfatherList_;
    ~vector_Of_father(){};
    vector_Of_father() : MyfatherList_(){};

  father vec_get( int i) { return(*(MyfatherList_.at(i))); };

  void WhoAmI(int i) const
  {
    MyfatherList_[i]->WhoAmI(); 
  };
  int size(){ return(MyfatherList_.size()); };
 

  void push_back(father func){
    MyfatherList_.push_back(make_shared<father>(func));
  };
  void push_back_children1_t(children1_t func){
    MyfatherList_.push_back(make_shared<children1_t>(func));
  };
};



-------------- the module code

RCPP_MODULE(mod_example2){
  using namespace Rcpp;
  
  class_<father>( "father" )
	//constructors  
	  .constructor()
    .method("WhoAmI",&father::WhoAmI)
	;
  
  class_<children1_t>( "children1_t" )
    .derives<father>("father" )
	//constructors
	  .constructor()
    .method("WhoAmI",&children1_t::WhoAmI)
	;
  
  class_<children2_t>( "children2_t" )
    .derives<father>("father" )
	//constructors
	  .constructor()
    .method("WhoAmI",&children2_t::WhoAmI)
	;
   
  class_<vector_Of_father>( "vector_Of_father")
    .constructor()
   // .constructor<int>()
    .method( "size", &vector_Of_father::size)
 // .method("capacity", &cplfunctionvec::capacity,"Return size of allocated storage capacity. Returns the size of the storage space currently allocated for the vector, expressed in terms of elements.")
//  .method( "max_size", &cplfunctionvec::max_size)
    .method( "WhoAmI",&vector_Of_father::WhoAmI )
    //.method( "test",&vector_Of_father::test )
    .method( "push_back", &vector_Of_father::push_back )
    .method("push_back_children1_t",&vector_Of_father::push_back_children1_t)
//  .const_method( "at", &cplfunctionvec::at )
    .method("[[",&vector_Of_father::vec_get)
  //  .method("[[<-",&vector_Of_father::vec_set)
  ;

}


Dr. Girard Robin
Chargé de Recherche

MINES-ParisTech / Département Energétique et Procédés / PERSEE / Groupe ERSEI
Centre Procédés, Energies Renouvelables et Systèmes Energétiques (PERSEE)
Center for Processes, Renewables Energies and Energy Systems
Renewable Energies & Smartgrids (ERSEI)

1 Rue Claude Daunesse - CS 10207 - F-06904 Sophia Antipolis Cedex
Tel: +33.4.93.67.89.64 (~99), Fax: +33.4.93.95.75.35
e-mail : robin.girard at mines-paristech.fr

web page perso http://www.mines-paristech.fr/Services/Annuaire/&?id=8828
statoverflow : http://stats.stackexchange.com/users/223/robin-girard
web page centre PERSEE : http://www.cep.mines-paristech.fr/
linkedin : http://www.linkedin.com/profile/view?id=14907272&trk=tab_pro

Le lien vaut mieux que le bien.
________________________________________________________

CONFIDENTIALITY : This  e-mail  and  any attachments are
confidential and may be privileged. If  you are not a
named recipient, please notify the sender immediately and
do not disclose the contents to another person, use it for
any purpose or store or copy the information in any medium.

CONFIDENTIALITE : Ce message et les éventuelles pièces
attachées sontconfidentiels et peuvent être une
communication protégée. Si vous n'êtes pas dans la liste
des destinataires, veuillez informer l'expéditeur
immédiatement et ne pas ouvrir ni divulguer le contenu
à une tierce personne, ne pas l'utiliser pour quelque
raison que ce soit, ne pas stocker ou copier l'information
qu'il contient sur un quelconque support.


More information about the Rcpp-devel mailing list