我不知道究竟爲什麼在博客中的代碼是(大概)有效,當它被寫,不再編譯,但那是大約三年前,和一些變化到Rcpp的Modules組件已經發生。要獲得此代碼編譯,你可以在你的類定義之前添加以下內容:
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);
我把完整的代碼從羅曼的C++爲例(見下圖,有幾個小的修改),只是爲了方便是能夠運行R代碼裏面也包含在博客文章:
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
的完整代碼(你的編譯器會抱怨沒有一個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)
;
};
謝謝!後續問題:我如何爲結構做同樣的事情?我需要聲明'struct myStruct;'然後執行'RCPP_EXPOSED_CLASS(myStruct);'還是有不同的宏來暴露結構? – Carl
相同的宏('RCPP_EXPOSED_CLASS')應該可以很好地用'struct'工作。就我可以告訴宏只需要'class' /'struct'的名稱來生成必要的樣板代碼('wrap <>'和'<>')來說明。 – nrussell