2016-08-01 3 views
-7

죄송합니다. 지금 제 질문을 수정했습니다. 대담한 유형의 단어에주의를 기울이시기 바랍니다.C++ 재귀 생성자를 정의하는 표준 방법은 무엇입니까?

정말 kdtree 클래스를 정의하는 동안 재귀 생성자가 필요합니다. 하지만 올바른 방법으로하고있는 것이 아닙니다. 더 우아하게 어떻게 할 수 있습니까?

이것은 포인터가를 컴파일하고 잘 작동 를 사용하여 내 코드입니다. 아무 것도하지 마십시오., 그냥 은 재귀 생성자가 어떤 모양을 보여야하는지에 대한 간략한 아이디어를 보여줍니다..

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

이것은 내 kdtree 샘플 코드입니다. 이것은 내가 실현하려고 노력하고있는 것입니다., 여전히 이 컴파일되지 않습니다., 나중에 편집하겠습니다.

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; 
    } 
    } 
}; 
+5

내게 꽤 무의미 해 보입니다. 실제로 달성하기를 원하십니까? –

+0

달성하려는 목표는 무엇입니까? 바로 a와 b를 0으로 설정할 수 있습니다 :-) –

+1

정말 이상한 일이 절실히 필요하다는 것을 정말로 믿지 않습니다. 그것은 XY 문제가되어야합니다. –

답변

0

생성자는 한 가지만 작성하므로 생성자를 사용하여 그룹을 구성 할 수 없습니다.

새로운 클래스 [20]을 사용하는 경우; // 20 개의 클래스가 할당되지만 각 클래스는 생성자에서 한 번 생성됩니다. 생성자를 호출 할 때마다에서

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

는, 생성자 만이 생성되는 객체 (X의 데이터를 기반으로)는 재귀 적으로이 일을하는 사실을 다루는 일종의 다르다. 이 경우 클래스는 트리에 많이 묶여 트리를 만들지 않고 쉽게 구성 할 수 없습니다. 그렇습니다 (의견에서) 가능하지만 실제로는 권장할만한 것은 아닙니다.

당신이 (예를 들어, 나무)를 저장할 항목의 그룹이있는 경우, 일반적인 빌딩 블록

  1. Item 있습니다 - 당신이 나무에 저장 한 것 (객체).
  2. Node - 나무를 이해하고 나무를 가로 지르는 개체.
  3. TreeContainer - 트리의 상단을 보유, 저장 찾을 방법을 알고있는 객체 Item
  4. Builder - 데이터를 가져 와서 TreeContainer
  5. 의 호출 방법으로 트리에 추가합니다 객체 또는 함수
+2

"생성자를 사용하여 그룹을 구성 할 수 없습니다." 나는이 주장을 쉽게 반증 할 수 있다고 생각한다. –

+1

좀 더 심각한 측면에서, 나는 ctor가 구축하고있는 많은 실제적인 것을 빌드하는 것이 불가능해야하는 이유를 알지 못한다; 마찬가지로 노드 ctor는 전체 트리를 만들고, 몇 번 호출하여 생성 된 노드의 주소를 적절한 분기 포인터에 할당합니다. 이것이 영업 사원이 달성하고자하는 목표 일 것입니다. –

+1

또한 꼭 필요한 경우 이러한 모든 역할을 단일 노드 클래스로 변환 할 수 있다고 생각합니다. 당신이 만드는 구별은 언어 부과가 아니라 논리적입니다. –

관련 문제