From 6f3a42f6b5d20d78ee960df25f0ba4914b9b5716 Mon Sep 17 00:00:00 2001 From: Ralf Stubner Date: Sun, 10 Feb 2019 12:55:07 +0100 Subject: [PATCH 1/2] Add example for .factory --- vignettes/Rcpp-modules.Rmd | 66 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/vignettes/Rcpp-modules.Rmd b/vignettes/Rcpp-modules.Rmd index f934eb8b3..5cc7d08a8 100644 --- a/vignettes/Rcpp-modules.Rmd +++ b/vignettes/Rcpp-modules.Rmd @@ -855,6 +855,72 @@ It can be used to perform operations, releasing resources, etc ... The finalizer is called automatically when the \proglang{R} object that encapsulates the \proglang{C++} object is garbage collected. +### Object factories + +The `.factory` member function of `class_` can be used to register a +[factory](https://en.wikipedia.org/wiki/Factory_method_pattern) that +can be used as alternative to a constructor. A factory can be a +static member function or a free function that returns a pointer to +the target class. Typical use-cases include creating objects in a +hierarchy: + +```c++ +#include +using namespace Rcpp; + +// abstract class +class Base { + public: + virtual ~Base() {} + virtual std::string name() const = 0; +}; + +// first derived class +class Derived1: public Base { + public: + Derived1() : Base() {} + virtual std::string name() const { + return "Derived1"; + } +}; + +// second derived class +class Derived2: public Base { + public: + Derived2() : Base() {} + virtual std::string name() const { + return "Derived2"; + } +}; + +Base *newBase( const std::string &name ) { + if (name == "d1"){ + return new Derived1; + } else if (name == "d2"){ + return new Derived2; + } else { + return 0; + } +} + +RCPP_MODULE(mod) { + Rcpp::class_< Base >("Base") + .factory(newBase) + .method("name", &Base::name); +} +``` + +The `newBase` method returns a pointer to a `Base` object. Since that +class is an abstract class, the objects are actually instances of +`Derived1` or `Derived2`. The same behavior is now available in R: + +```{r, eval=FALSE} +dv1 <- new(Base, "d1") +dv1$name() # returns "Derived1" +dv2 <- new(Base, "d2") +dv2$name() # returns "Derived2" +``` + ### S4 dispatch When a \proglang{C++} class is exposed by the `class_` template, From 41bc596c17526dca596d834d18c14c5d84aea0a2 Mon Sep 17 00:00:00 2001 From: Ralf Stubner Date: Sun, 10 Feb 2019 17:08:38 +0100 Subject: [PATCH 2/2] Replace c++ by cpp --- vignettes/Rcpp-modules.Rmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vignettes/Rcpp-modules.Rmd b/vignettes/Rcpp-modules.Rmd index 5cc7d08a8..b95487623 100644 --- a/vignettes/Rcpp-modules.Rmd +++ b/vignettes/Rcpp-modules.Rmd @@ -864,7 +864,7 @@ static member function or a free function that returns a pointer to the target class. Typical use-cases include creating objects in a hierarchy: -```c++ +```cpp #include using namespace Rcpp;