Ruby C++扩展中的多个构造函数
Multiple constructors in Ruby C++ extension
我构建了ruby C++扩展。我在C++中有多个构造函数。所以我创建了几个initialize方法。但它显示了一个错误。非常感谢。
这是我的密码。
C++头文件
#ifndef CIRCLE_H_
#define CIRCLE_H_
class Circle {
public:
Circle():_radius(0.0) {}
Circle(float radius):_radius(radius) {}
float getArea() { return 3.14159 * _radius * _radius; }
void setRadius(float radius) { _radius=radius; }
private:
float _radius;
};
#endif /* CIRCLE_H_ */
cpp文件
#include<ruby.h>
#include"Circle.h"
#include<iostream>
using namespace std;
VALUE classOb;
template<class Obtype> void delete_objects(Obtype *ptr){// free pointer
delete ptr;
}
template<class Obtype> VALUE wrap_pointer(VALUE klass,Obtype *ptr){ //wrap c++ object to ruby object
return Data_Wrap_Struct(klass,0,delete_objects,ptr);
}
VALUE alloc_ob(VALUE self){
return wrap_pointer<Circle>(self,new Circle());// add c++ object to ruby object
}
VALUE method_initialize(VALUE self,VALUE y){
double x= NUM2DBL(y);
Circle *c;
Data_Get_Struct(self,Circle,c);
c->setRadius(x);
return self;
}
VALUE method_Initialize(VALUE self){
.......
return ;
}
............
extern "C" void Init_Test(){
VALUE lemon = rb_define_module("Test");
classOb= rb_define_class_under(lemon,"Circle",rb_cObject);
rb_define_alloc_func(classOb,alloc_ob);
rb_define_method(classOb, "initialize", (VALUE(*)(ANYARGS))method_initialize,0);
rb_define_method(classOb, "initialize", (VALUE(*)(ANYARGS))method_initialize,1);
rb_define_method(classOb, "test1", (VALUE(*)(ANYARGS))method_initialize,0);
}
extconf.rb
require 'mkmf'
have_library( 'stdc++' );
$CFLAGS << " -Wall"
create_makefile( 'Test' );
test.rb
require 'rubygems'
require '/home/kelum/workspace/Test3/circle/Test'
include Test
obj=Circle.new
obj2=Circle.new(7.1)
出现错误
Circle.cpp:47:61: error: overloaded function with no contextual type information
Circle.cpp:48:61: error: overloaded function with no contextual type information
问题出在哪里?
不能有两个采用不同参数的initialize
方法,并让Ruby在它们之间进行选择。这是Ruby的一个限制,与C++构造函数的行为不同。从技术上讲,无论如何,Ruby initialize
都是在构造后发生的——Ruby已经生成了对象,并且不使用任何params。
相反,你有两个选项
1)允许initialize
获取可变数量的参数,并自己检测不同的可能性
初始化方法:
VALUE method_initialize( int argc, VALUE* argv, VALUE self ) {
VALUE y;
// You'll want to read up on rb_scan_args
rb_scan_args( argc, argv, "01", &y );
Circle *c;
Data_Get_Struct( self, Circle, c );
// Only set radius if y is not nil
if ( ! NIL_P( y ) ) {
c->setRadius( NUM2DBL(y) );
}
return self;
}
如何将其绑定到类:
rb_define_method( classOb, "initialize", method_initialize, -1 );
(注意-1
,Ruby的信号,该方法采用可变数量的参数)
2)使用不同名称的"工厂"方法,并自己处理构建新对象
工厂方法:
VALUE method_from_radius( VALUE self, VALUE y ) {
double x= NUM2DBL(y);
volatile VALUE new_circle = alloc_ob( self );
Circle *c;
Data_Get_Struct( new_circle, Circle, c);
c->setRadius(x);
return new_circle;
}
这种变化也是可能的(也许最接近你的目标):
VALUE method_from_radius( VALUE self, VALUE y ) {
double x= NUM2DBL(y);
return wrap_pointer<Circle>(self,new Circle( x ));
}
如何将其绑定到类:
rb_define_singleton_method( classOb, "from_radius", method_from_radius, 1 );
请注意,在Ruby中操作singleton方法时,其行为与实例方法不同。您可能需要extend Test
和include Test
。
问题是您试图绑定两个构造函数:
Circle():_radius(0.0) {}
Circle(float radius):_radius(radius) {}
Ruby没有重载的方法,而且它很难处理。
尝试删除默认构造函数,并将默认值传递给另一个构造函数。
希望能有所帮助。
相关文章:
- "error: no matching function for call to"构造函数错误
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 选择要调用的构造函数
- 如何委托派生类使用其父构造函数?
- 构造函数正在调用一个使用当前类类型的函数
- 没有用于初始化C++中的变量模板的匹配构造函数
- 初始化具有非默认构造函数的std::数组项的更好方法
- 当从函数参数中的临时值调用复制构造函数时
- 在c++构造函数中使用随机字符串生成器
- 一对向量构造函数:初始值设定项列表与显式构造
- 从构造函数抛出异常时如何克服内存泄漏
- 我不明白为什么我声明一个空的内部结构并将其传递给构造函数
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 具有默认模板类型的默认构造函数的类型推导
- 使用dynamic_cast和构造函数时出错
- 在c++中使用向量时,如何调用构造函数和析构函数
- 奇怪的构造函数行为