-5

Sorry, I edited my question now .Pay attention to the bold type words .

I really need a recursive constructor while defining a kdtree class . But I'm afraid I'm not doing it the right way . How can I do it more elegantly ?

This is my code using the this pointer ,it compiles and works well . Don't do anything at all ,just showing the brief idea of what a recursive constructor should look like .

#include <iostream>
using namespace std;

class foo
{
public:
  int a, b;
  foo(unsigned int k)//this piece of code just shows the brief idea of what i'm trying to do.
  {
    if (k)
      *this = foo(--k);
    else
      a = k, b = k;
  }
};

int main()
{
  foo f(3);
  cout << f.a << f.b << endl;
  getchar();
}

This is my kdtree sample code .This is what I'm actully trying to achieve ,still don't compile ,I'll edit it later.

class kdtree
{
public:
  int16_t count;//数组里面可以只存mask和key生成的unique_key,因为树结构,和count可以后期生成
  int16_t key;
  int16_t mask;
  inline bool is_full()
  {
    return mask + count == 0x8000;
  };
  shared_ptr<kdtree> left, right;
  kdtree(){}
  kdtree(int x1, int y1, int z1, int x2, int y2, int z2, int _x = 0, int _y = 0, int _z = 0, int len = 0, int ikey = 0x8000)
  {
    int i = 0x80 >> len / 3, j = 0x4000 >> len;
    if ((x2 - x1)*(y2 - y1)*(z2 - z1) == j << 10)
    {
      count = j << 1;
      key = ikey;
      mask = ~ikey ^ (ikey - 1);
      return;
    }
    switch (len++ % 3)
    {
    case 0:
      if (x1 < _x&&x2 < _x)
      {
        *this = kdtree(x1, y1, z1, x2, y2, z2, _x, _y, _z, len, ikey -= j);
        return;
      }
      if (x1 >= _x&&x2 >= _x)
      {
        *this = kdtree(x1, y1, z1, x2, y2, z2, _x + i, _y, _z, len, ikey += j);
        return;
      }
      left = shared_ptr<kdtree>(new kdtree(x1, y1, z1, _x, y2, z2, _x, _y, _z, len, ikey -= j));
      right = shared_ptr<kdtree>(new kdtree(_x, y1, z1, x2, y2, z2, _x + i, _y, _z, len, key += j));
      count = j << 1;
      key = ikey;
      mask = ~ikey ^ (ikey - 1);
      return;
    case 1:
      if (y1 < _y&&y2 < _y)
      {
        *this = kdtree(x1, y1, z1, x2, y2, z2, _x, _y, _z, len, ikey -= j);
        return;
      }
      if (y1 >= _y&&y2 >= _y)
      {
        *this = kdtree(x1, y1, z1, x2, y2, z2, _x, _y + i, _z, len, ikey += j);
        return;
      }
      left = shared_ptr<kdtree>(new kdtree(x1, y1, z1, x2, y2, z2, _x, _y, _z, len, ikey -= j));
      right = shared_ptr<kdtree>(new kdtree(x1, y1, z1, x2, y2, z2, _x, _y + i, _z, len, ikey += j));
      count = j << 1;
      key = ikey;
      mask = ~ikey ^ (ikey - 1);
      return;
    case 2:
      if (x1 < _x&&x2 < _x)
      {
        *this = kdtree(x1, y1, z1, x2, y2, z2, _x, _y, _z, len, ikey);
        return;
      }
      if (x1 >= _x&&x2 >= _x)
      {
        *this = kdtree(x1, y1, z1, x2, y2, z2, _x, _y, _z + i, len, ikey + j);

      }
      left = shared_ptr<kdtree>(new kdtree(x1, y1, z1, x2, y2, _z, _x, _y, _z, len, ikey));
      right = shared_ptr<kdtree>(new kdtree(x1, y1, _z, x2, y2, z2, _x, _y, _z + i, len, ikey + j));
      count = j << 1;
      key = ikey;
      mask = ~ikey ^ (ikey - 1);
      return;
    }
  }
};
iouvxz
  • 609
  • 8
  • 22

1 Answers1

0

A constructor only builds one thing, so you can't use a constructor to build a group of things.

If you use new Class[ 20]; // 20 Classes get allocated, but each is constructed once in the constructor.

class Class
{
    Class * left;
    Class * right;
    Class(  SomeObject & x )
    {
         eatSomeData( x );
         left = nullptr;
         right = nullptr;
         if (x->buildleft() )
             left = new Class( x );
         if (x->buildright() )
             right = new Class( x );
    }
};

At each call to the constructor, the constructor only deals with the object it is creating, the fact it is doing this recursively (based on the data in x), is sort of different. In this case the class is heavily bound into the tree, and can't be easily constructed without building a tree. Yes it is possible (from comments), but really really not advisable.

If you have a group of items you want to store (e.g. a tree), the typical building blocks are

  1. Item - the thing (object) you store in the tree.
  2. Node - an object which understands the tree, and how to traverse the tree.
  3. TreeContainer - an object which holds the top of the tree, and which knows how to find stored Items
  4. Builder - an object or function which takes your data and adds it into the tree by calling methods of the TreeContainer
mksteve
  • 11,552
  • 3
  • 24
  • 45
  • 2
    "you can't use a constructor to build a group of things." I think this claim is easily refutable ;-). – Peter - Reinstate Monica Aug 01 '16 at 05:51
  • 1
    On a more serious side, I don't see why it should be impossible to even build a number of the actual things the ctor is building; like, a node ctor creates a whole tree, calling itself a couple times and assigning the addresses of the created nodes to the proper branch pointers. That's probably what the OP tries to achieve. – Peter - Reinstate Monica Aug 01 '16 at 06:03
  • 1
    I also think you can fold all these roles into a single node class, if you must; the distinctions you make are logical rather than language-imposed. – Peter - Reinstate Monica Aug 01 '16 at 06:23