2016-06-04 2 views
2

저는 C++과 그와 함께 제공되는 모든 메모리 관리에 상당히 익숙합니다.함수에서 생성 된 객체를 멤버 변수에 할당

내 문제는 내가 을 확장 한 다음 클래스가 데이터가 InVec 객체 인 이진 트리입니다 (같은 클래스의 또 다른 목적에 멤버 변수에 상기 물체를 할당하는 기능의 개체를 만들 수 있다는 것입니다). 함수가 실행 된 후

의 메모리 위치 그러나 간접 참조 값 정크이다가 동일한 소정 SPnode위한m_right을 m_left.

나는 때문에 객체가 범위를 벗어나려고하므로, 항복 포인터 점 정크에 m_leftm_right 파괴되는 InVecSPnode이인지 거의 확실 해요.

내 질문은 : 함수 내에서 개체를 만들고, 멤버 변수에 할당하고, 함수가 종료 될 때이를 파괴하지 않는 방법은 무엇입니까? 분명히 뭔가 빠져있는 것이 틀림 없습니다.하지만 어디서나 답을 찾을 수 없었습니다 (나는 문구를 잘 모르겠습니다). 이 코드는 나쁜 형태 인 경우 사과 또는 내가 몇 가지 중요한 규칙을 위반하고있어 경우

void expand(SPnode &ASP) 
{ 
    if (!(ASP.isLeaf())) return; 

    int axis(ASP.m_box.getWidthAxis()); 
    Interval width(ASP.m_box.getWidth()); 

    InVec lowerInVec(lower(ASP.m_box, width, axis)); 
    InVec upperInVec(upper(ASP.m_box, width, axis)); 


    SPnode leftChild(lowerInVec); 
    std::cout << &leftChild << "\n"; 

    SPnode rightChild(upperInVec); 
    std::cout << &rightChild << "\n"; 


    ASP.m_left = &leftChild; 
    std::cout << (ASP.m_left) << "\n"; 

    ASP.m_right = &rightChild; 
    std::cout << (ASP.m_right) << "\n"; 
} 

- 어떤 건설적인 비판도 감상 할 수있다 :

여기 내 코드입니다.

편집 : 당신은 동적 노드를 할당해야합니다

// The Interval class is the base object on which all other classes in this 
// module are built. Its implementation is intuitive, as all mathematical 
// operations that are relevant for nonlinear image computation are given 
// as overloaded operators (i.e. intervalA + intervalB returns the expected 
// result from basic interval arithmetic). 
class Interval 
{ 
private: 

    // infimum (lower bound) of interval 
    double m_inf; 

    //supremum (upper bound) of interval 
    double m_sup; 

public: 
    Interval(double inf, double sup): m_inf(inf), m_sup(sup) {} 

    // getter member functions, where getLen returns the length of the interval 
    // and getMidpt returns the midpoint 
    double getInf() const {return m_inf;} 
    double getSup() const {return m_sup;} 
    double getLen() const {return m_sup - m_inf;} 
    double getMidpt() const {return (m_inf + m_sup)/2.0;} 


// --- Headers ----------------------------------------------------------------- 

    // determines if a double is in the interval 
    bool containsVal(double val) const; 

    // determines if another interval is contained in the interval 
    bool contains(const Interval &other) const; 

    // performs scalar multiplication on the interval 
    Interval scalarMul(double scal) const; 


    // operator overloading - the specifics of interval arithmetic can be found 
    // in a book or online 
    friend Interval operator+(const Interval &intA, const Interval &intB); 
    friend Interval operator-(const Interval &intA, const Interval &intB); 
    friend Interval operator*(const Interval &intA, const Interval &intB); 
    friend bool operator==(const Interval &intA, const Interval &intB); 
    friend bool operator!=(const Interval &intA, const Interval &intB); 
    friend std::ostream& operator<< (std::ostream &out, const Interval &intA); 


    friend void expand(SPnode &ASP); 
    friend InVec lower(const InVec &box, const Interval &width, int axis); 
    friend InVec upper(const InVec &box, const Interval &width, int axis); 
}; 

class InVec 
{ 
private: 

    // this is a vector containing the Interval objects that make up the InVec 
    // object 
    std::vector<Interval> m_intervals; 

public: 

    InVec(std::vector<Interval> intervals): m_intervals(intervals) {} 

    // returns m_intervals 
    std::vector<Interval> getIntervals() const {return m_intervals;} 

    // returns the interval at given axis (i.e. index) in m_intervals 
    Interval getInterval(int axis) const {return m_intervals.at(axis);} 

    // sets the interval at given axis to given Interval object 
    void setInterval(int axis, const Interval &intA) 
    {m_intervals.at(axis) = intA;} 


// --- Headers ----------------------------------------------------------------- 

    // determines if another InVec object is contained in this InVec object 
    bool contains(const InVec &IVB) const; 

    // returns the length of the largest Interval object in m_intervals - note 
    // that it is necessary to compute this first, before the actual largest 
    // Interval can be determined 
    double getWidthSize() const; 

    // returns the Interval in m_intervals with the longest length 
    // (i.e. the width) 
    Interval getWidth() const; 


    // returns the axis (i.e. index) on which the width occurs 
    double getWidthAxis() const; 


    // operator overloading 
    friend InVec operator+(const InVec &IVA, const InVec &IVB); 
    friend InVec operator-(const InVec &IVA, const InVec &IVB); 
    friend InVec operator*(const InVec &IVA, const InVec &IVB); 
    friend bool operator==(const InVec &intA, const InVec &intB); 
    friend bool operator!=(const InVec &intA, const InVec &intB); 
    friend std::ostream& operator<< (std::ostream &out, const InVec &IVA); 


    friend void expand(SPnode &ASP); 
    friend InVec lower(const InVec &box, const Interval &width, int axis); 
    friend InVec upper(const InVec &box, const Interval &width, int axis); 

}; 

class SPnode 
{ 
private: 

    InVec m_box; 

    // left and right children of this SPnode object - note that these must be 
    // pointers in order to use them in the definition of the class, otherwise 
    // SPnode would have an inifinite definition 
    SPnode* m_left; 
    SPnode* m_right; 

public: 

    SPnode(InVec box): m_box(box), m_left(NULL), m_right(NULL) {} 


    // getters and setters 
    InVec getBox() const {return m_box;} 
    SPnode* getLeft() const {return m_left;} 
    SPnode* getRight() const {return m_right;} 
    void setBox(const InVec box) {m_box = box;} 
    void setLeft(SPnode* const p_node) {m_left = p_node;} 
    void setRight(SPnode* const p_node) {m_right = p_node;} 

    bool isLeaf() const; 

    friend std::ostream& operator<< (std::ostream &out, const SPnode &ASP); 
    friend void expand(SPnode &ASP); 
    friend InVec lower(const InVec &box, const Interval &width, int axis); 
    friend InVec upper(const InVec &box, const Interval &width, int axis); 
}; 
+0

'SPnode'와'InVec'의 정의를 보여줄 수 있습니까? –

답변

0

당신은 포인터로 차일을 만들고 동적으로 다음과 같이이를 할당하는 new 연산자를 사용한다 :

SPnode * leftChild = new SPnode(lowerInVec); 

그리고이 같은 객체의 멤버 변수에 할당이 :

ASP.m_left = leftChild; 

을 또한 다음과 같이 m_left를 SPnode 포인터로 선언해야합니다.

SPNode * m_left; 

올바른 것을 똑같이하십시오.

Ps .: 스마트 포인터를 이해하기 전에 new 연산자를 사용하여 할당 한 포인터를 이해해야합니다.

+0

감사합니다. 나는 _new_ 연산자에 완전히 익숙하지 않기 때문에 그것에 대해 읽어야 할 것이다. – duncster94

2

: 여기 간격, InVec 및 SPnode에 대한 관련 코드입니다. 그리고 스마트 포인터로 메모리를 관리해야하는 것보다 - 가장 가능성이 높은 것은 std::unique_ptr입니다. 이 인수의 SPNode 생성자가 기준 (또는 주소)를 유지하려고하지 않습니다 제안에

ASP.m_left = std::make_unique<SPnode>(lowerInVec); 

에 :

코드는 무엇인가 등이 될 것입니다. 만약 그렇다면, 논쟁은 역동적으로 할당되어야 할 것이다.

+0

감사합니다. 스마트 포인터에 대한 독서를해야 할 것입니다. – duncster94

관련 문제