在另一个 class 的构造函数中使用 class 作为参数
Using a class as a parameter in a constructor of another class
我读了这个 blog post 关于 Rcpp 中的 classes 和模块的文章,我试图重新创建它,但我遇到了麻烦。
这是 post:
中代码的简化版本
#include <Rcpp.h>
using namespace Rcpp;
class Point {
public:
Point( double x_, double y_) : x(x_), y(y_){}
double x, y ;
} ;
class Shape {
public:
Shape( const Point& center_ ) : center(center_){}
Point center ;
virtual double area() const { return 0.0 ;}
virtual bool contains(const Point& point) const { return false ; }
} ;
RCPP_MODULE(play){
class_<Point>("Point")
.constructor<double,double>()
.field( "x", &Point::x)
.field( "y", &Point::y)
;
class_<Shape>( "Shape" )
.constructor<Point>()
.method( "area", &Shape::area )
.method( "contains", &Shape::contains )
;
};
这里发生的所有事情都是创建点 class,然后在形状 class 的构造函数中用作参数。但是 Shape class 不会接受 Point class 作为构造函数中的参数。当我编译上面的代码时,我得到了错误:没有匹配函数来调用“Point::Point(SEXPREC*&)”。我相信这个错误是说 Shape 的构造函数不理解如何处理 Point class.
我已经阅读了 Springer Rcpp
教科书中关于模块的章节,并且我阅读了关于模块的小插图,但我不相信他们中的任何一个都有构建 classes 的示例来自其他 classes,如上述博客 post。我一定是误解了什么,所以如果有人能启发我,我将不胜感激。
此致
我不确定确切地为什么该博客 post 中的代码在编写时(大概)有效并且不再编译,但那是大约三年前,从那时起,Rcpp 的模块组件发生了一些变化。要编译它,您可以在 class 定义之前添加以下内容:
class Point; // fwd declarations
class Shape;
class Circle;
class Rectangle;
RCPP_EXPOSED_CLASS(Point);
RCPP_EXPOSED_CLASS(Shape);
RCPP_EXPOSED_CLASS(Circle);
RCPP_EXPOSED_CLASS(Rectangle);
我从 Romain 的 C++ 示例中获取了完整的代码(见下文,有一些小的修改)只是为了方便 运行 博客中也包含的 R 代码 post:
origin <- new( Point, 0, 0 )
pie <- new( Circle, origin, 3 )
##
R> pie$area()
#[1] 28.27433
R> pie$contains( new( Point, 1, 2 ) )
#[1] TRUE
##
rec <- new( Rectangle, origin, 2, 3 )
R> rec$area()
#[1] 6
R> rec$contains( new( Point, 1, 2 ) )
#[1] FALSE
完整代码(您的编译器会抱怨 Shape
中没有 virtual
析构函数):
#include <Rcpp.h>
class Point; // fwd declarations
class Shape;
class Circle;
class Rectangle;
RCPP_EXPOSED_CLASS(Point);
RCPP_EXPOSED_CLASS(Shape);
RCPP_EXPOSED_CLASS(Circle);
RCPP_EXPOSED_CLASS(Rectangle);
class Point {
public:
Point( double x_, double y_) : x(x_), y(y_){}
double x, y ;
} ;
double square( double x) {
return x*x ;
}
double distance( const Point& p1, const Point& p2 ){
return sqrt( square( p1.x - p2.x) + square( p1.y - p2.y ) ) ;
}
class Shape {
public:
Shape( const Point& center_ ) : center(center_){}
virtual ~Shape() {}
Point center ;
virtual double area() const { return 0.0 ;}
virtual bool contains(const Point& point) const { return false ; }
} ;
class Circle : public Shape {
public:
Circle( Point center_, double radius_ ): Shape(center_), radius(radius_){}
double area() const {
return PI * square( radius ) ;
}
bool contains( const Point& point ) const {
return distance(point, center) < radius ;
}
double radius ;
} ;
class Rectangle : public Shape {
public:
Rectangle( Point center_, double width_, double height_ ) :
Shape(center_), width(width_), height(height_){}
double area() const {
return width * height ;
}
bool contains( const Point& point ){
return (point.x >= ( center.x - width / 2.0 )) &&
(point.x <= ( center.x + width / 2.0 )) &&
(point.y >= ( center.y - height / 2.0 )) &&
(point.y <= ( center.y + height / 2.0 ));
}
double width, height ;
} ;
RCPP_MODULE(play){
using namespace Rcpp;
class_<Point>("Point")
.constructor<double,double>()
.field( "x", &Point::x)
.field( "y", &Point::y)
;
class_<Shape>( "Shape" )
.constructor<Point>()
.method( "area", &Shape::area )
.method( "contains", &Shape::contains )
;
class_<Circle>( "Circle" )
.derives<Shape>("Shape" )
.constructor<Point,double>()
.field( "r", &Circle::radius )
;
class_<Rectangle>( "Rectangle" )
.derives<Shape>("Shape" )
.constructor<Point,double,double>()
.field( "h", &Rectangle::height )
.field( "w", &Rectangle::width )
;
};
我读了这个 blog post 关于 Rcpp 中的 classes 和模块的文章,我试图重新创建它,但我遇到了麻烦。
这是 post:
中代码的简化版本#include <Rcpp.h>
using namespace Rcpp;
class Point {
public:
Point( double x_, double y_) : x(x_), y(y_){}
double x, y ;
} ;
class Shape {
public:
Shape( const Point& center_ ) : center(center_){}
Point center ;
virtual double area() const { return 0.0 ;}
virtual bool contains(const Point& point) const { return false ; }
} ;
RCPP_MODULE(play){
class_<Point>("Point")
.constructor<double,double>()
.field( "x", &Point::x)
.field( "y", &Point::y)
;
class_<Shape>( "Shape" )
.constructor<Point>()
.method( "area", &Shape::area )
.method( "contains", &Shape::contains )
;
};
这里发生的所有事情都是创建点 class,然后在形状 class 的构造函数中用作参数。但是 Shape class 不会接受 Point class 作为构造函数中的参数。当我编译上面的代码时,我得到了错误:没有匹配函数来调用“Point::Point(SEXPREC*&)”。我相信这个错误是说 Shape 的构造函数不理解如何处理 Point class.
我已经阅读了 Springer Rcpp
教科书中关于模块的章节,并且我阅读了关于模块的小插图,但我不相信他们中的任何一个都有构建 classes 的示例来自其他 classes,如上述博客 post。我一定是误解了什么,所以如果有人能启发我,我将不胜感激。
此致
我不确定确切地为什么该博客 post 中的代码在编写时(大概)有效并且不再编译,但那是大约三年前,从那时起,Rcpp 的模块组件发生了一些变化。要编译它,您可以在 class 定义之前添加以下内容:
class Point; // fwd declarations
class Shape;
class Circle;
class Rectangle;
RCPP_EXPOSED_CLASS(Point);
RCPP_EXPOSED_CLASS(Shape);
RCPP_EXPOSED_CLASS(Circle);
RCPP_EXPOSED_CLASS(Rectangle);
我从 Romain 的 C++ 示例中获取了完整的代码(见下文,有一些小的修改)只是为了方便 运行 博客中也包含的 R 代码 post:
origin <- new( Point, 0, 0 )
pie <- new( Circle, origin, 3 )
##
R> pie$area()
#[1] 28.27433
R> pie$contains( new( Point, 1, 2 ) )
#[1] TRUE
##
rec <- new( Rectangle, origin, 2, 3 )
R> rec$area()
#[1] 6
R> rec$contains( new( Point, 1, 2 ) )
#[1] FALSE
完整代码(您的编译器会抱怨 Shape
中没有 virtual
析构函数):
#include <Rcpp.h>
class Point; // fwd declarations
class Shape;
class Circle;
class Rectangle;
RCPP_EXPOSED_CLASS(Point);
RCPP_EXPOSED_CLASS(Shape);
RCPP_EXPOSED_CLASS(Circle);
RCPP_EXPOSED_CLASS(Rectangle);
class Point {
public:
Point( double x_, double y_) : x(x_), y(y_){}
double x, y ;
} ;
double square( double x) {
return x*x ;
}
double distance( const Point& p1, const Point& p2 ){
return sqrt( square( p1.x - p2.x) + square( p1.y - p2.y ) ) ;
}
class Shape {
public:
Shape( const Point& center_ ) : center(center_){}
virtual ~Shape() {}
Point center ;
virtual double area() const { return 0.0 ;}
virtual bool contains(const Point& point) const { return false ; }
} ;
class Circle : public Shape {
public:
Circle( Point center_, double radius_ ): Shape(center_), radius(radius_){}
double area() const {
return PI * square( radius ) ;
}
bool contains( const Point& point ) const {
return distance(point, center) < radius ;
}
double radius ;
} ;
class Rectangle : public Shape {
public:
Rectangle( Point center_, double width_, double height_ ) :
Shape(center_), width(width_), height(height_){}
double area() const {
return width * height ;
}
bool contains( const Point& point ){
return (point.x >= ( center.x - width / 2.0 )) &&
(point.x <= ( center.x + width / 2.0 )) &&
(point.y >= ( center.y - height / 2.0 )) &&
(point.y <= ( center.y + height / 2.0 ));
}
double width, height ;
} ;
RCPP_MODULE(play){
using namespace Rcpp;
class_<Point>("Point")
.constructor<double,double>()
.field( "x", &Point::x)
.field( "y", &Point::y)
;
class_<Shape>( "Shape" )
.constructor<Point>()
.method( "area", &Shape::area )
.method( "contains", &Shape::contains )
;
class_<Circle>( "Circle" )
.derives<Shape>("Shape" )
.constructor<Point,double>()
.field( "r", &Circle::radius )
;
class_<Rectangle>( "Rectangle" )
.derives<Shape>("Shape" )
.constructor<Point,double,double>()
.field( "h", &Rectangle::height )
.field( "w", &Rectangle::width )
;
};