Προς το περιεχόμενο

class data member of its own type χωρίς recursion και statically allocated


Προτεινόμενες αναρτήσεις

Δημοσ. (επεξεργασμένο)

Έστω η παρακάτω κλάση, πως θα μπορούσα να την γράψω διαφορετικά χωρίς recursion (data member ιδιο με τον τυπο της κλάσης), πχ το Edge *next ή Edge *Rot() και με static allocation (pre-allocation, πχ Edge[100] next) όχι pointer δλδ.

class QuadEdge;

class Edge
{
    friend QuadEdge;
    friend void Splice(Edge *, Edge *);

private:
    int num;
    Edge *next;
    Point2d *data;

public:
    Edge() { data = 0; }
    Edge *Rot();
    Point2d *Org();
    const Point2d &Org2d() const;
    void EndPoints(Point2d *, Point2d *);
    QuadEdge *Qedge() { return (QuadEdge *)(this - num); }
};

class QuadEdge
{
    friend Edge *MakeEdge();

private:
    Edge e[4];

public:
    QuadEdge();
};

 

Επεξ/σία από Dr.Fuzzy
  • Moderators
Δημοσ.

Κάτι τέτοιο σου κάνει;

class EdgeInterface
{
    EdgeInterface() {}
    virtual ~EdgeInterface() {}
};

class Edge : public EdgeInterface
{
    public:
        Edge();
        ~Edge();
        std::array<EdgeInterface, 100> next;
};

 

  • Thanks 1
Δημοσ. (επεξεργασμένο)
16 hours ago, Kercyn said:

Κάτι τέτοιο σου κάνει;


class EdgeInterface
{
    EdgeInterface() {}
    virtual ~EdgeInterface() {}
};

class Edge : public EdgeInterface
{
    public:
        Edge();
        ~Edge();
        std::array<EdgeInterface, 100> next;
};

Ωραίος αλλά δυστυχώς δεν έχω array library διαθέσιμη.

Επεξ/σία από Dr.Fuzzy
  • Moderators
Δημοσ. (επεξεργασμένο)

Ε κάνε όπως στο παράδειγμά σου, EdgeInterface[100]. Τώρα επειδή εσύ γενικά δουλεύεις με κάτι περίεργα πράγματα του Σατανά, αν έχεις και κάποιον άλλον περιορισμό πες μήπως μπορέσουμε να βοηθήσουμε πιο στοχευμένα.

Επεξ/σία από Kercyn
Δημοσ.
7 hours ago, Kercyn said:

Τώρα επειδή εσύ γενικά δουλεύεις με κάτι περίεργα πράγματα του Σατανά, αν έχεις και κάποιον άλλον περιορισμό πες μήπως μπορέσουμε να βοηθήσουμε πιο στοχευμένα.

Χαχαχα πράγματι! Λοιπόν κάτσε να το δοκιμάσω και θα επανέλθω.

Δημοσ.

Επανέρχομαι. Λοιπόν κατάφερα να βρω μια synthesizable έκδοση του array container οπότε είμαστε καλά. Τελικά θέλω να υλοποιήσω το παρακάτω οπότε με το next μπλέκει το πράγμα.

inline QuadEdge::QuadEdge()
{
	e[0].num = 0, e[1].num = 1, e[2].num = 2, e[3].num = 3;
	e[0].next = &(e[0]);
	e[1].next = &(e[3]);
	e[2].next = &(e[2]);
	e[3].next = &(e[1]);
    	e[0].next = {0};
}

inline Edge* Edge::Rot()
{
	return (num < 3) ? this + 1 : this - 3;
}

 

Δημοσ. (επεξεργασμένο)
18 hours ago, Kercyn said:

Κάτσε γιατί δεν κατάλαβα καλά, ποιο είναι το πρόβλημα τώρα;

Βασικά incompatibles types στο = (το next πριν υλοποιούσε ένα instance του εαυτού του, πρακτικά ένα stack, θεωρητικά το ίδιο κάνει και τώρα αλλά με static allocation με το ap_array).

Επεξ/σία από Dr.Fuzzy
Δημοσ. (επεξεργασμένο)

Λοιπόν προφανώς μου χτυπάει εδώ e[0].next = &(e[0]);

Quote

error: no viable overloaded '='
 e[0].next = &(e[0]);

note: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'Edge *' to 'const ap_array<EdgeInterface, 100>' for 1st argument;
struct ap_array

 

Επεξ/σία από Dr.Fuzzy
Δημοσ.
15 minutes ago, Kercyn said:

Αν καταλαβαίνω καλά πας να θέσεις σε pointer ένα array. Θες να βάλεις και τον κώδικα;

Δες εδώ, είναι βάσει της αρχικής λύσης χωρίς recursion και static allocation που έκανες post.

class QuadEdge;

class EdgeInterface {
public:
	EdgeInterface() {
	}
	virtual ~EdgeInterface() {
	}
};

class Edge: public EdgeInterface {
	friend QuadEdge;
private:
	int num;
	//EdgeInterface *next;
	ap_array<EdgeInterface, 100> next;
	Point2d *data;
public:
	Edge() { data = 0; }
	Edge* Rot();
	QuadEdge* Qedge() {
        return (QuadEdge *) (this - num);
	}
};

class QuadEdge {
	friend Edge *MakeEdge();
private:
	Edge e[4];
public:
	QuadEdge();
};
      
inline QuadEdge::QuadEdge() {
	e[0].num = 0, e[1].num = 1, e[2].num = 2, e[3].num = 3;
	e[0].next = &(e[0]);
	e[1].next = &(e[3]);
	e[2].next = &(e[2]);
	e[3].next = &(e[1]);
}
      
inline Edge* Edge::Rot() {
	return (num < 3) ? this + 1 : this - 3;
}

Edge* MakeEdge() {
	QuadEdge *ql = new QuadEdge;
	return ql->e;
}

 

  • Moderators
Δημοσ.

Δεν καταλαβαίνω το όλο σκεπτικό. Έχεις ένα array το οποίο έχει μέσα edges. Μετά πας και του λες ότι σε αυτή τη μεταβλητή τύπου array πήγαινε και βάλε τη διεύθυνση ενός μόνο edge. Γιατί θέλεις το next να είναι array αν το χρησιμοποιείς έτσι; Μήπως θες αυτά τα QuadEdge::e να τα κάνεις append στο next;

Δημοσ. (επεξεργασμένο)
1 hour ago, Kercyn said:

Δεν καταλαβαίνω το όλο σκεπτικό. Έχεις ένα array το οποίο έχει μέσα edges. Μετά πας και του λες ότι σε αυτή τη μεταβλητή τύπου array πήγαινε και βάλε τη διεύθυνση ενός μόνο edge. Γιατί θέλεις το next να είναι array αν το χρησιμοποιείς έτσι; Μήπως θες αυτά τα QuadEdge::e να τα κάνεις append στο next;

Λοιπόν, στον αρχικό κώδικα το next απλά κάνει point στην class Edge, δηλαδή στο επόμενο edge.

class Edge {
	friend QuadEdge;
	friend void Splice(edge*, edge*);
private:
	int num;
	edge *next;
	point *data;
public:
	edge() {data = 0;}
	edge* Rot();
};

οπότε,

inline QuadEdge::QuadEdge() {
	e[0].num = 0, e[1].num = 1, e[2].num = 2, e[3].num = 3;
	e[0].next = &(e[0]); e[1].next = &(e[3]);
	e[2].next = &(e[2]); e[3].next = &(e[1]);
}

και επίσης, πχ,

inline Edge* Edge::Rot() {
// Return the dual of the current edge, directed from its right to its left.
	return (num < 3) ? this + 1 : this - 3;
}

inline Edge* Edge::Onext() {
// Return the next ccw edge around (from) the origin of the current edge.
	return next;
}

inline Edge* Edge::Oprev() {
// Return the next cw edge around (from) the origin of the current edge.
	return Rot()->Onext()->Rot();
}

το πρόβλημα εδώ λόγω του ουυυ εξω απο εδώ 666 είναι ότι δεν μπορώ να χρησιμοποιήσω recursion ούτε dynamic allocation! Οπότε φτάνουμε στη λύση που πρότεινες αρχικά με το interface και το array container. To allocated size πρεπει να ειναι γνωστο precompile, πχ pointer σε fixed size array ειναι ΟΚ.

Επεξ/σία από Dr.Fuzzy
Δημοσ.

Αν κατάλαβα καλά θες να βάλεις object της κλάσης με has-A relation μέσα στο definition της κλάσης. Αυτό αν δεν κάνω λάθος είναι αδύνατο καθώς τη στιγμή που ο compiler τρέχει το definition πρέπει με κάποιο τρόπο να καταλάβει πόση μνήμη χρειάζεται να δεσμεύσει για κάθε instance της. Εδώ έχεις left recursion, γραμματικά δεν κάνει parse. Όπως και στη C αν βάλεις πεδίο τύπου struct A μέσα στο definition του struct A δεν θα κάνει compile.

Με pointer περνά καθώς οι pointers έχουν ίδια χωρητικότητα ανεξαρτήτως πού κοιτούν (όσο το word size).

Δημοσ.

Αυτό που Θέλω είναι με κάποιο τρόπο να υλοποιήσω ένα pointer στην class ως member variable (δηλ. pointer to self type) χωρίς recursion και με fixed size.

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...