2016-06-04 22 views
2

So bin ich ziemlich neu in C++ und all die Speicherverwaltung, die damit einhergeht.Zuweisen von Objekt erstellt in Funktion zu Member-Variable

Mein Problem ist, dass ich ein Objekt in der Funktion erweitert erstellen und dann das Objekt auf ein variablen Elemente zuweisen in einem anderen Objekt der gleichen Klasse (die Klasse ist ein binärer Baum, wo seine Daten ist ein InVec Objekt).

Nachdem die Funktion ausgeführt wird, m_left der Speicherplatz und m_right für einen gegebenen SPnode gleich sind, jedoch ist die Werte dereferenzierte Junk sind.

Ich bin fast sicher, dass dies aufgrund der InVec und SPnode ist Objekte außerhalb des Gültigkeitsbereichs gehen und zerstört zu werden, wodurch man Zeiger m_left und m_right, die auf Junk.

Meine Frage ist: Wie erstelle ich ein Objekt innerhalb einer Funktion, weisen Sie es einer Membervariablen zu und lassen Sie es nicht zerstören, wenn die Funktion beendet wird? Ich bin sicher, ich vermisse etwas Offensichtliches, aber ich konnte nirgends eine Antwort finden (ich bin mir nicht einmal sicher, wie ich das ausdrücken soll).

Hier ist mein Code:

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

ich entschuldige mich, wenn dieser Code schlechte Form ist, oder wenn ich ein paar wichtige Regeln bin gegen - jede konstruktive Kritik auch anerkannt werden würde.

EDIT: Hier ist der entsprechende Code für Interval, InVec und SPnode:

// 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

Können Sie die Definition von 'SPnode' und' InVec' anzeigen? –

Antwort

0

Sie sollten Ihre Childs als Zeiger und verwenden Sie den neuen Operator erstellen, um sie dynamisch zuweisen, wie folgt aus:

SPnode * leftChild = new SPnode(lowerInVec); 

Und das assign es auf das Objekt Membervariable wie folgt aus:

ASP.m_left = leftChild; 

Außerdem sollten Sie m_left als SPnode-Zeiger deklarieren:

Machen Sie dasselbe mit dem richtigen.

Ps .: Bevor Sie intelligente Zeiger verstehen, sollten Sie Zeiger verstehen, die mit dem neuen Operator zugewiesen werden.

+0

Danke, das hat funktioniert. Ich bin mit dem _new_ Operator nicht ganz vertraut, also muss ich darüber nachlesen. – duncster94

2

Sie müssen dynamisch Ihre Knoten zuweisen. Und dann müssten Sie diesen Speicher mit einem intelligenten Zeiger verwalten - höchstwahrscheinlich std::unique_ptr.

Code wäre so etwas wie:

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

Die in Vorschlag ist, dass SPNode Konstruktor nicht versucht, den Verweis zu halten (oder eine Adresse), um es Argument ist. Wenn dies der Fall ist, müsste dieses Argument ebenfalls dynamisch zugewiesen werden.

+0

Danke dafür, ich muss etwas über intelligente Zeiger lesen. – duncster94