2016-06-07 2 views
-1

"tree"라는 수퍼 클래스를 만들었습니다. 나는이 수업에서 나무를 만들었다. 이제는 생성 된 트리의 루트를 트리의 서브 클래스 인 다른 클래스에 전달하려고합니다. 하지만 그것을 전달하려고하면 하위 클래스가 supercalss 생성자를 호출하고 NULL로 설정합니다.수퍼 클래스에서 C++의 서브 클래스로 값을 전달하는 방법

struct node 
{ 
    struct node *left; 
    struct node *right; 
    int val; 
}; 
struct node *create(int val) 
{ 
    struct node *temp = (struct node *)malloc(sizeof(struct node)); 
    temp->val = val; 
    temp->left = temp->right = NULL; 
    return temp; 
}; 
class tree 
{ 
    public: 
     struct node *root; 
     tree() 
     { 
      root = NULL; 

     } 
     void createtree() 
     { 
      root = create(5); 
     } 
     void preorder() 
     { 
      preorderp(root); 
     } 
     void preorderp(struct node *p) 
     { 
      if(!p) { 
       return; 
      } 
      cout<<p->val<<' '; 
      preorderp(p->left); 
      preorderp(p->right); 
     } 
}; 

이것은 내 트리 클래스의 정의입니다. 이제는 값이 5 인 노드가 하나만있는 트리를 만듭니다. 이제 트리의 하위 클래스에 생성 된 새 루트를 전달하려고합니다.

class treeiterator:public tree 
{ 
    struct node *p; 
    stack<struct node *> s; 
    public: 
     treeiterator() 
     { 
      p = root; 
      push(root); 
     } 
     bool hasnext(); 
     int next(); 
    private: 
     void push(struct node *root); 
}; 

먼저 나무 용 개체를 만든 다음 createtree를 만듭니다. 자, treeiterator에 대한 객체를 만들 때 supercalss 생성자가 호출되기 때문에 멤버 p는 NULL로 설정됩니다. 하위 클래스의 수퍼 클래스에서 만든 트리에 어떻게 액세스 할 수 있습니까? 전체 코드 :

#include <bits/stdc++.h> 
using namespace std; 
struct node 
{ 
    struct node *left; 
    struct node *right; 
    int val; 
}; 
struct node *create(int val) 
{ 
    struct node *temp = (struct node *)malloc(sizeof(struct node)); 
    temp->val = val; 
    temp->left = temp->right = NULL; 
    return temp; 
}; 
class tree 
{ 
    public: 
     struct node *root; 
     tree() 
     { 
      root = NULL; 

     } 
     void createtree() 
     { 
      root = create(5); 
     } 
     void preorder() 
     { 
      preorderp(root); 
     } 
     void preorderp(struct node *p) 
     { 
      if(!p) { 
       return; 
      } 
      cout<<p->val<<' '; 
      preorderp(p->left); 
      preorderp(p->right); 
     } 


}; 
class treeiterator:public tree 
{ 
    struct node *p; 
    stack<struct node *> s; 
    public: 
     treeiterator() 
     { 
      p = root; 
      push(root); 
     } 
     bool hasnext(); 
     int next(); 
    private: 
     void push(struct node *root); 
}; 
void treeiterator::push(struct node *t) 
{ 
    while(t) { 
     s.push(t); 
     t = t->left; 
    } 
} 
bool treeiterator::hasnext() 
{ 
    return s.empty()?1:0; 
} 
int treeiterator::next() 
{ 
    struct node *t = s.top(); 
    int val = t->val; 
    s.pop(); 
    if(t->right) { 
     push(t->right); 
    } 
    return val; 
} 
int main() 
{ 
    tree t; 
    t.createtree(); 
    t.preorder(); 
    treeiterator it; 
    while(it.hasnext()) { 
     cout<<it.next()<<' '; 
    } 
} 
+1

왜 C++에서'new' 대신'malloc()'을 사용하고 있습니까? – MikeCAT

+0

필요가 없습니다. 'root'는 공개입니다, 잠깐. 다시 읽으면서 나는 그것을 본다라고 생각한다. 'treeiterator'를 만들 때'tree'가 내장되어 있습니다.'tree'를 만들 필요가 없습니다. 'treeiterator'에서'createtree'를 호출해야하지만, 나는 [RAII를 읽어 보길 권한다] (http://en.cppreference.com/w/cpp/language/raii)와 생성자에서 초기화를 수행하는 것이 좋습니다. – user4581301

+0

@ user4581301 : 자세히 설명해 주시겠습니까? –

답변

0

첫째, 당신은 루트 public을 가지고 안됩니다. 이것은 총체 공용어 오류입니다. 하위 클래스에서 사용할 수 있도록하려면 protected으로 지정해야합니다.

1

모든 상속 때문에 treeiterator도 모두 tree입니다. 즉,

treeiterator treeIt; 
treeIt.createtree(); 

은 OP가 원하는 것을 수행합니다. 별도의 tree을 만들고 root을 움직일 필요가 없습니다.

그러나 OP가 생성자를 사용하고 있지 않기 때문에 이것은 C++의 세계에서 조금 이상합니다. 예를 들어, node가 될 수있다 :

struct node 
{ 
    node *left; 
    node *right; 
    int val; 

    node(int inval): 
     val(inval), 
     left(nullptr), 
     right(nullptr) 
     // the above is a Member Initializer List. It makes sure all of your 
     // members are initialized before the body of the constructor runs. 
    { 
    } 
}; 

생성자에서 : 후 그 비트가 Member Initializer List입니다. 이제 node을 할당하면 초기화되고 연결 준비가되었습니다. tree

class tree 
{ 
    public: 
     struct node *root; // almost certainly should not be public. 
          // also should be a std::unique_ptr<node> 
     tree(int inval) 
     { 
      root = new node(5); // note new in place of malloc. new allocates 
           // storage and calls constructors. malloc should 
           // only be used in C++ in rare edge-cases. 
     } 
     /* obsolete 
     void createtree() 
     { 
      root = create(5); 
     } 
     */ 
     ... 
}; 

tree 위해 할당 root에 할당된다. treeiteratortree의 생성자를 호출하여 root을 설정해야하기 때문에 약간 까다 롭습니다. treeiterator 할당

class treeiterator:public tree 
{ 
    struct node *p; // Don't see the point off this 
    stack<struct node *> s; // or this, but that's another question 
    public: 
     treeiterator(int inval): 
      tree(inval) // call's tree's constructor 
     { 
     } 
     bool hasnext(); 
     int next(); 
    private: 
     void push(struct node *root); 
}; 

지금은 더 이상의 작업과 함께 갈 모든 준비가되어 있음을 보장합니다.

treeiterator treeIt(5); // all done. 

위의 내용은 모두 the first few chapters of any good C++ programming text입니다. 당신은 신속하게 코드의 규칙을 위반 한 것을 발견하려고

을 : 지금 당신이 주제 1 꺼짐 나쁜 C.

를 작성하려고하는 모양 때문에, 하나를 얻고 그것을 읽어 보시기 바랍니다 세. What is The Rule of Three? 모르는 경우 링크를 읽으십시오. 그것은 당신에게 많은 시간과 저장됩니다 헤어 당겨 주제 2 끄기

을 :

#include <bits/stdc++.h> 
using namespace std; 

은 시한 폭탄입니다.첫 번째 라인은 전체 표준 라이브러리를 포함하지만 GCC에서만 존재합니다. 이제는 코드가 컴파일 작업보다 훨씬 더 많이 수행되고 더 이상 표준 C++이 아니며 다른 컴파일러로 이식 할 수 없으며 GCC의 다음 개정판과 잘 어긋납니다. bits에 아무것도 사용하지 마십시오. 그것은 내부 컴파일러 특정 물건을 보장하지 않고 무엇 - 그래서 - 적 -. 여기

더 : Why should I not #include <bits/stdc++.h>?

두 번째 줄은 std 네임 스페이스와 글로벌 네임 스페이스에 배치합니다 모든 것을합니다. 이것은 reverse 또는 std::reverse과 같은 재미있는 게임으로 연결됩니까? 빈약 한 컴파일러가 지옥처럼 혼란 스럽기 때문에 이것은 종종 미숙하고 모호한 컴파일러 메시지를 낳습니다. 그러나 때로는 혼란스럽지 않고 많은 사람들 사이에서 최상의 선택을 선택하고 조용히 다른 것을 끊습니다. 재미있는 디버깅. 여기

더 : Why is "using namespace std" considered bad practice?

는 함께 당신은 전체 표준 라이브러리 파일에 들어갔습니다 그리고 적절한 네임 스페이스의 박탈있다. 이로 인해 잠재적으로 숨겨진 아픔의 광대 한 지뢰밭이 생겨 어떤인지 된 시간 절약의 가치가 없습니다. 결과 버그 중 하나는 파일과 문자 당 몇 줄을 추가로 입력하는 것보다 더 많은 정리 작업을 수행 할 수 있습니다.

아무도이 바보 같은 실수로 코드를 정리하지 않으므로 전문적인 환경에서이 작업을 수행하는 데 많은 비용이 듭니다.

관련 문제