这几天在写R*树,使用模板类遇到一堆问题。直接上代码:
rectangle.h
#ifndef __H_RECTANGLE_H__
#define __H_RECTANGLE_H__
#include "point.h"
using namespace std;
namespace R_START_TREE
{
template <std::size_t dimensions>
class Rectangle
{
private:
Point<dimensions> lowerLeft, upperRight;
public:
Rectangle()
{
lowerLeft.reset();
upperRight.reset();
}
Rectangle(double ll[], double ur[], int size)
{
if(size != getDimension())
{
printf("[Rectangle::Rectangle()] length of the array is not equal to the dimension, please check it!\n");
}
lowerLeft.setCoordinateValue(ll, size);
upperRight.setCoordinateValue(ur, size);
}
Rectangle(Point<dimensions> &ll, Point<dimensions> &ur)
{
for (size_t i = 0; i < dimensions; i++)
{
if (ll.getCoordinateValue(i) > ur.getCoordinateValue(i))
{
printf("[Rectangle::Rectangle()] First param should \
be the lower left quarter, and the second be the upper \
right quarter of the rectangle, please check it!\n");
//throw IllegalArgumentException();
reset();
return;
}
if (ll.getCoordinateValue(i) == ur.getCoordinateValue(i))
{
printf("[Rectangle::Rectangle()] The %d-th numberic of \
ll and ur are the same, it is not a %d-D rectangle, please \
check it!\n",
i, dimensions);
//throw IllegalArgumentException();
reset();
return;
}
lowerLeft = ll;
upperRight = ur;
}
}
~Rectangle()
{
reset();
}
int getDimension()
{
return sizeof(lowerLeft)/sizeof(double);
}
void reset()
{
lowerLeft.reset();
upperRight.reset();
}
std::string toString()
{
std::string sBuffer = "(";
sBuffer.append(lowerLeft.toString()).append(", ").append(upperRight.toString()).append(")");
return sBuffer;
}
Point<dimensions> getLowerLeft()
{
return lowerLeft;
}
Point<dimensions> getUpperRight()
{
return upperRight;
}
void setLowerLeft(Point<dimensions> ll)
{
lowerLeft = ll;
}
void setUpperRight(Point<dimensions> ur)
{
upperRight = ur;
}
};
};
#endif // __H_RECTANGLE_H__
它是基于Point类来实现的。
point.h
#ifndef __H_POINT_H__
#define __H_POINT_H__
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <cstddef>
#include <memory>
using namespace std;
namespace R_START_TREE
{
template <std::size_t dimensions>
class Point
{
private:
double coordinate_value[dimensions];
public:
Point(double data[], int size)
{
if (data == NULL)
{
printf("[Point::Point()] Coordinates cannot be null.\n"); // ★坐标不能为空
//throw IllegalArgumentException();
}
if (size != dimensions)
{
printf("Point dimension in the param is not the same as required. The dimension required is %d, please check the param.\n", dimensions);
//throw new IllegalArgumentException("Point dimension should be greater than 1."); // ★点的维度必须大于1
}
//printf("sizeof(data) = %d\n",sizeof(data));
memcpy(coordinate_value, data, size * sizeof(double)); // 复制数组
}
~Point()
{
reset();
}
int getDimension()
{
return sizeof(coordinate_value) / sizeof(double);
}
double *getCoordinateValue()
{
return coordinate_value;
}
double getCoordinateValue(int index)
{
return coordinate_value[index];
}
void setCoordinateValue(double data[], int size)
{
if(size != getDimension())
{
printf("size of the data is not equal to the dimension corresponding to the coordinate_value.\n");
//throw new IllegalArgumentException("");
}
else
{
memcpy(coordinate_value, data, size* sizeof(double));
}
}
void reset()
{
memset(coordinate_value, 0, sizeof(coordinate_value));
}
string toString()
{
std::string sBuffer = "(";
for (int i = 0; i < getDimension() - 1; i++)
{
sBuffer.append(std::to_string(coordinate_value[i])).append(",");
}
sBuffer.append(std::to_string(coordinate_value[getDimension() - 1])).append(")"); // 最后一位数据后面不再添加逗号,追加放在循环外面
return sBuffer;
}
bool equals(Point point)
{
if (point.getDimension() != getDimension()) // 维度相同的点才能比较
{
printf("[Point::equals()] Points must be of equal dimensions to be compared.");
//throw new IllegalArgumentException("Points must be of equal dimensions to be compared.");
}
for (int i = 0; i < getDimension(); i++)
{
if (getCoordinateValue(i) != point.getCoordinateValue(i))
return false;
}
return true;
}
Point& operator=(const Point & point)
{
if(this != &point)
{
memcpy(this->coordinate_value, point.coordinate_value, getDimension()*sizeof(double));
}
return *this;
}
};
};
#endif //__H_POINT_H__
main.cpp
#include "../include/rectangle.h"
#include <unistd.h>
/**
* 测试Point类的功能
**/
using namespace R_START_TREE;
using namespace std;
int main(int argc, char **argv)
{
const std::size_t dimension = 3;
bool flag = false;
double ll[dimension] = {1.0, 2.0, 3.0};
double ur[dimension] = {100.0,110,120};
Point<dimension> point1(ll, 3),point2(ur,3);
Rectangle<dimension> rect1(point1, point2),rect2(point2, point1);
std::cout<< "Rect1: "<< rect1.toString()<<std::endl;
std::cout<< "Rect2: "<< rect2.toString()<<std::endl;
return 0;
}
在编译的时候报错,不管看懂看不懂,直接看到说rectangle.h的21行不匹配,你会发现21行只是两个Point类的对象作为形参,应该没问题啊。
经过仔细分析,发现在Rectangle类中的两个私有变量lowerLeft和upperRight,在声明时调用了默认的无参构造函数。而在Point类中,并没有无参构造函数。只需要加上去就可以了。增加如下代码:
Point()
{
reset();
}