I'm finding that accessor methods on a wrapped C++ class end up creating

extra objects on the Ruby side. Here's an example to illustrate:

The following Ruby code uses two wrapped C++ classes (Point and Edge) in

the shared library TSP.so. An

Edge has two Point objects and the 'start_node' and 'end_node' methods on

Edge return Point objects.

#test_point.rb

require 'TSP'

include TSP

def count_points

np = 0

ObjectSpace.each_object(Point){|p|

np+=1

}

np

end

pa = Point.new(2,3)

pb = Point.new(10,6)

puts "number of points should be 2: count_points=#{count_points}"

edge = Edge.new(pa,pb,(pa-pb))

puts "number of points should be 2: count_points=#{count_points}"

puts edge.start_node #<-here's where the trouble starts

puts edge.end_node

puts "number of points should be 2: count_points=#{count_points}"

#end test_point.rb

Running test_point.rb prints:

making a new Point at 2,3

making a new Point at 10,6

number of points should be 2: count_points=2

number of points should be 2: count_points=2

(2,3)

(10,6)

number of points should be 2: count_points=4

So after calling the accessor methods 'start_node' and 'end_node' the

number of Point objects is 4 instead of 2. I think this is being caused

by SWIG_NewPointerObj. Maybe there's no way around it. I would have

expected that I would get a reference to an already existing Point object

instead of a new Point object being created.

Is there any way to do this so that no new Point objects are created when

calling Edge#end_node, Edge#start_node? Since my script calls these

methods a lot, lots of extra Point objects get created.

Here are the point.h/cpp and edge.h/cpp files:

#include <iostream>

class Point

{

// attr_accessor :x, :y

private:

int x_;

int y_;

//Point(Point& x){};

public:

Point(int x,int y):x_(x),y_(y){std::cout << "making a new Point at "

<< x <<","<<y<< std::endl;}

Point(Point& p){std::cout << "copy constructor" << std::endl;}

//calculate the distance between this point and other point

float operator -(Point& o);

bool operator ==(Point& o);

//accessors:

int x(){ return x_; }

int y(){ return y_; }

};

float Point::operator -(Point& o){

return sqrt((x_ - o.x())*(x_ - o.x())+(y_-o.y())*(y_ - o.y()));

};

bool Point::operator ==(Point& o){

return ((x_==o.x())&&(y_==o.y()));

};

#include "point.h"

class Edge

{

private:

Point* start_node_;

Point* end_node_;

float length_;

float tao_;

float quality_factor_;

public:

//constructor:

Edge(Point* s_node, Point* e_node, float len, float tao=TAO0);

//accessors

float length() const{return length_;}

Point* start_node() const {return start_node_;}

Point* end_node() const {return end_node_;}

float quality_factor() const { return quality_factor_;}

float tao() const {return tao_;}

void set_tao(float new_tao){ tao_ = new_tao; }

void calc_quality_factor();

};

#include "edge.h"

#include <math.h>

Edge::Edge(Point* s_node, Point* e_node, float len, float

tao):start_node_(s_node),end_node_(e_node),length_ (len),tao_(tao){

this->calc_quality_factor();

}

void Edge::calc_quality_factor(){

quality_factor_=(tao_ * (pow((1.0/length_),BETA)) );

}

///end C++ code

Here is the TSP.i file:

%module TSP

%{

#include "constants.h"

#include "point.h"

#include "edge.h"

%}

%alias Edge::set_tao "tao=";

%include "constants.h"

%include "point.h"

%include "edge.h"