Hi,
I've got some issues by using the copy constructor of the S4 class.
I want to make a copy of a S4 object but it looks like the copy constructor returns a reference instead of a new instance of the S4 class.
I made a dummy example to illustrate my problem:
##############################################################
setClass(
Class="ResultObject",
representation=representation(
data = "numeric"
),
prototype=prototype(
data = numeric(0)
)
)
##############################################################
##############################################################
setClass(
Class="TestObject",
representation=representation(
size = "numeric",
results = "ResultObject"
),
prototype=prototype(
size = numeric(0),
results = new("ResultObject")
)
)
##############################################################
##############################################################
src <- '
Rcpp::S4 obj(S4Object);
// get the size
int n = obj.slot("size");
// get a copy of the ResultObject by calling the copy constructor
// --> but here it looks like a reference not a copy ?
Rcpp::S4 res(obj.slot("results"));
// if size is greater than create a list of results
if ( n > 1 ){
// create a new list
Rcpp::List resList(n);
// loop over the results
for (int i=0; i<n; i++ ){
// save results into the S4 object
res.slot("data") = i;
// copy the S4 object into the list --> so it looks like a copy of a reference here...
resList[i]=res;
}
// set the list to our S4 object
obj.slot("results") = resList;
}
// otherwise store only one result
else if ( n == 1 ){
res.slot("data") = 1;
obj.slot("results") = res;
}
// return the S4 object
return obj;
'
testList <- cxxfunction(signature(S4Object="TestObject"), src, plugin = "Rcpp")
##############################################################
# test with 3 elements
# all data slot will contain the same value, that's not what we expect
test1<-new("TestObject", size=3)
testList(test1)
# test with only one element
test2<-new("TestObject", size=1)
testList(test2)
Any idea how to make a copy of a S4 object?
R?mi
R?mi Lebret
Ing?nieur de recherche CNRS
Laboratoire de math?matiques de Lille1 - UMR 8524
Batiment M3 - Bureau 322
Tel: 03 20 43 67 82
remi.lebret at math.univ-lille1.fr
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20120216/db7c8ab7/attachment-0001.html>
[Rcpp-devel] Problem with the copy constructor of Rcpp::S4
3 messages · Douglas Bates, Rémi Lebret
On Thu, Feb 16, 2012 at 9:25 AM, R?mi Lebret
<remi.lebret at math.univ-lille1.fr> wrote:
Hi,
I've got some issues by using the copy constructor of the S4 class.
I want to make a copy of a S4 object but it looks like the copy constructor
returns a reference instead of a new instance of the S4 class.
I made a dummy example to illustrate my problem:
##############################################################
setClass(
? Class="ResultObject",
? representation=representation(
? ? data = "numeric"
? ),
? prototype=prototype(
? ? data = numeric(0)
? )
)
##############################################################
##############################################################
setClass(
? Class="TestObject",
? representation=representation(
? ? size = "numeric",
? ? results = "ResultObject"
? ),
? prototype=prototype(
? ? size = numeric(0),
? ? results = new("ResultObject")
? )
)
##############################################################
##############################################################
src <- '
? Rcpp::S4 obj(S4Object);
? // get the size
? int n = obj.slot("size");
? // get a copy of the ResultObject by calling the copy constructor
? // --> but here it looks like a reference not a copy ?
? Rcpp::S4 res(obj.slot("results"));
? // if size is greater than create a list of results
? if ( n > 1 ){
? ? // create a new list
? ? Rcpp::List resList(n);
? ? // loop over the results
? ? for (int i=0; i<n; i++ ){
? ? ? // save results into the S4 object
? ? ? res.slot("data") = i;
? ? ? // copy the S4 object into the list -->? so it looks like a copy of a
reference here...
? ? ? resList[i]=res;
? ? }
? ? // set the list to our S4 object
? ? obj.slot("results") = resList;
? }
? // otherwise store only one result
? else if ( n == 1 ){
? ? res.slot("data") = 1;
?? ? obj.slot("results") = res;
? }
? // return the S4 object
? return obj;
'
testList <- cxxfunction(signature(S4Object="TestObject"), src, plugin =
"Rcpp")
##############################################################
# test with 3 elements
# all data slot will contain the same value, that's not what we expect
test1<-new("TestObject", size=3)
testList(test1)
# test with only one element
test2<-new("TestObject", size=1)
testList(test2)
Any idea how to make a copy of a S4 object?
You probably want to clone the object, not use the copy constructor.
That is, (not tested)
Rcpp::S4 res(Rcpp::clone(obj.slot("results"));
Hi Douglas,
I've tried that: Rcpp::S4 res(Rcpp::clone(Rcpp::S4(obj.slot("results")));
But it doesn't solve the problem because you actually clone the reference returned by the copy constructor...
R?mi
Le 16 f?vr. 2012 ? 17:25, Douglas Bates a ?crit :
On Thu, Feb 16, 2012 at 9:25 AM, R?mi Lebret <remi.lebret at math.univ-lille1.fr> wrote:
Hi,
I've got some issues by using the copy constructor of the S4 class.
I want to make a copy of a S4 object but it looks like the copy constructor
returns a reference instead of a new instance of the S4 class.
I made a dummy example to illustrate my problem:
##############################################################
setClass(
Class="ResultObject",
representation=representation(
data = "numeric"
),
prototype=prototype(
data = numeric(0)
)
)
##############################################################
##############################################################
setClass(
Class="TestObject",
representation=representation(
size = "numeric",
results = "ResultObject"
),
prototype=prototype(
size = numeric(0),
results = new("ResultObject")
)
)
##############################################################
##############################################################
src <- '
Rcpp::S4 obj(S4Object);
// get the size
int n = obj.slot("size");
// get a copy of the ResultObject by calling the copy constructor
// --> but here it looks like a reference not a copy ?
Rcpp::S4 res(obj.slot("results"));
// if size is greater than create a list of results
if ( n > 1 ){
// create a new list
Rcpp::List resList(n);
// loop over the results
for (int i=0; i<n; i++ ){
// save results into the S4 object
res.slot("data") = i;
// copy the S4 object into the list --> so it looks like a copy of a
reference here...
resList[i]=res;
}
// set the list to our S4 object
obj.slot("results") = resList;
}
// otherwise store only one result
else if ( n == 1 ){
res.slot("data") = 1;
obj.slot("results") = res;
}
// return the S4 object
return obj;
'
testList <- cxxfunction(signature(S4Object="TestObject"), src, plugin =
"Rcpp")
##############################################################
# test with 3 elements
# all data slot will contain the same value, that's not what we expect
test1<-new("TestObject", size=3)
testList(test1)
# test with only one element
test2<-new("TestObject", size=1)
testList(test2)
Any idea how to make a copy of a S4 object?
You probably want to clone the object, not use the copy constructor.
That is, (not tested)
Rcpp::S4 res(Rcpp::clone(obj.slot("results"));
R?mi Lebret Ing?nieur de recherche CNRS Laboratoire de math?matiques de Lille1 - UMR 8524 Batiment M3 - Bureau 322 Tel: 03 20 43 67 82 remi.lebret at math.univ-lille1.fr -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20120216/89b467cf/attachment-0001.html>