在另一个类的构造函数中使用一个类作为参数 [英] Using a class as a parameter in a constructor of another class

查看:73
本文介绍了在另一个类的构造函数中使用一个类作为参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我阅读了这篇关于类和模块的博客文章Rcpp 和我试图重新创建它,但我遇到了问题.

I read this blog post about classes and modules in Rcpp and I tried to recreate it, but I am having trouble.

这是帖子中代码的缩写版本:

Here is an abbreviated version of the code from the 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 )
  ;
 
};

这里发生的所有事情都是创建 Point 类,然后在 Shape 类的构造函数中用作参数.但是 Shape 类不会接受 Point 类作为构造函数中的参数.当我编译上面的代码时,我得到错误:没有匹配的函数调用Point::Point(SEXPREC*&)".我相信这个错误是说 Shape 的构造函数不了解如何处理 Point 类.

All that is happening here is the Point class is created, and then used as a parameter in the constructor of the Shape class. But the Shape class won't accept the Point class as a parameter in the constructor. When I compile the above code I get the error: no matching function for call to "Point::Point(SEXPREC*&)". I believe this error is saying that the constructor for Shape doesn't understand how to handle the Point class.

我已经阅读了 Springer Rcpp 教科书中关于模块的章节,我阅读了关于模块的小插图,但我不相信他们中的任何一个都有从其他类构造类的例子,比如在上面的博客文章中.我一定是误会了什么,所以如果有人能启发我,我将不胜感激.

I have read the chapter in the Springer Rcpp textbook about modules, and I read the vignette about modules, but I don't believe any of them have examples where classes are constructed from other classes like in the above blog post. I must be misunderstanding something so I would appreciate if someone could enlighten me.

问候

推荐答案

我不确定究竟为什么那篇博文中的代码在编写时(大概)是有效的,而不再是编译,但那是大约三年前,从那时起对 Rcpp 的 Modules 组件进行了一些更改.要编译它,您可以在类定义之前添加以下内容:

I'm not sure exactly why the code in that blog post was (presumably) valid when it was written and is no longer compiling, but that was roughly three years ago, and some changes to the Modules component of Rcpp have taken place since then. To get this to compile, you can add the following before your class definitions:

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 代码:


I took the complete code from Romain's C++ example (see below, with a couple of minor modifications) just for the convenience of being able to run the R code also contained in the blog 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 析构函数):


Full code (your compiler will complain without a virtual destructor in Shape):

#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 )
  ;

};

这篇关于在另一个类的构造函数中使用一个类作为参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆