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

[C++] Vector με στοιχεία από άλλο vector


Kercyn

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

  • Moderators

Έστω ότι έχουμε τον παρακάτω κώδικα:

 

wMessageBox.h

 

 

 

enum class MsgboxType
{
    OK_CANCEL = 0,
    YES_NO,
    INFO,
    WARNING,
    ERROR
};

enum class MsgboxButtonID
{
    OK = 0,
    CANCEL,
    YES,
    NO,
};
 
struct MsgboxButton
{
    MsgboxButtonID id;
    std::string caption;
    SDL_Keycode hotkey;

    MsgboxButton(MsgboxButtonID id_, std::string caption_, SDL_Keycode hotkey_)
        : id(id_), caption(caption_), hotkey(hotkey_)
    {}
};
 
class wMessageBox
{
    protected:
        std::string title;
        std::string msg;
        MsgboxType type;

        static std::vector<MsgboxButton> buttonVec;
        static std::map<MsgboxType, std::vector<MsgboxButton>> buttonDesc;

    public:
        wMessageBox(std::string title_, std::string msg_, MsgboxType type_);
        virtual ~wMessageBox() = 0;
};

 

 

 

wMessageBox.cpp

 

 

 

vector<MsgboxButton> wMessageBox::buttonVec = {
    MsgboxButton(MsgboxButtonID::OK, "OK", SDL_SCANCODE_RETURN),
    MsgboxButton(MsgboxButtonID::CANCEL, "Cancel", SDL_SCANCODE_ESCAPE),
    MsgboxButton(MsgboxButtonID::YES, "Yes", SDL_SCANCODE_RETURN),
    MsgboxButton(MsgboxButtonID::NO, "No", SDL_SCANCODE_ESCAPE)
};

map<MsgboxType, vector<MsgboxButton>> wMessageBox::buttonDesc = {
    { MsgboxType::OK_CANCEL, vector<MsgboxButton>(&buttonVec[0], &buttonVec[1]) },
    { MsgboxType::YES_NO, vector<MsgboxButton>(&buttonVec[2], &buttonVec[3]) },
    { MsgboxType::INFO, vector<MsgboxButton>(&buttonVec[0], &buttonVec[0]) },
    { MsgboxType::WARNING, vector<MsgboxButton>(&buttonVec[0], &buttonVec[0]) },
    { MsgboxType::ERROR, vector<MsgboxButton>(&buttonVec[0], &buttonVec[0]) }
};
 
/* . . . */

 

 

 

Με αυτή την υλοποίηση δε μπορώ να επιλέγω αυθαίρετα ποια κουμπιά θα έχει ένα message box γιατί πρέπει να είναι διαδοχικά στο buttonVec. Δε μπορώ, δηλαδή, να φτιάξω ένα message box με τα κουμπιά OK, CANCEL και NO. Αυτό που έχω κάνει "δουλεύει" γιατί τα message boxes που θέλω αυτά είναι όλα κι όλα, αλλά τι θα γινόταν στην περίπτωση που ήθελα ένα messagebox με συγκεκριμένα κουμπιά; Ό,τι απάντηση έχω δει για subvectors έχει να κάνει με iterators...

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Για ποιό λόγο κρατάς vectors μέσα στο map? Ξεκίνα απο κει.

 

Πάντως σε C++11 είναι trivial να κάνεις αυτό που θέλεις χρησιμοποιώντας initializer list.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

  • Moderators

Για ποιό λόγο κρατάς vectors μέσα στο map? Ξεκίνα απο κει.

 

Πάντως σε C++11 είναι trivial να κάνεις αυτό που θέλεις χρησιμοποιώντας initializer list.

 

Δεν καταλαβα τιποτα.

 

To buttonVec έχει πληροφορίες για όλα τα πιθανά κουμπιά που μπορεί να έχει κάποιο messagebox.

Το buttonDesc έχει ένα υπο-vector, το οποίο περιέχει τα κουμπιά που έχει ένας συγκεκριμένος τύπος messagebox.

Αυτό που θέλω να κάνω είναι να παίρνω συγκεκριμένα στοιχεία (πχ το 1ο το 3ο και το 5ο) από το buttonVec και να τα βάζω στο υπο-vector του buttonDesc.

Αυτό που κάνω τώρα είναι να παίρνω ένα range από στοιχεία με iterators (πχ 1ο - 3ο).

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

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

Γιατί μου φαίνεται λίγο overkill να φτιάξω καινούριες κλάσεις για μια τόσο μικρή διαφοροποίηση. Απλώς επειδή μου φαίνεται ότι δεν είναι εύκολα επεκτάσιμο αυτό που έχω κάνει σκέφτηκα μήπως γίνεται αυτό που έλεγα. Όσο για το MessageBox::ShowInfo κλπ, θα φτιάξω messagebox manager μόλις τελειώσω με τα messageboxes. Ευχαριστώ πολύ.

 

Edit:

Μάλλον κατάλαβα αυτό που εννοούσες defacer. Αυτό εδώ;

 

map<MsgboxType, vector<MsgboxButton>> wMessageBox::buttonDesc = {
    { MsgboxType::OK_CANCEL, vector<MsgboxButton>() = { buttonVec[0], buttonVec[1]} },
    { MsgboxType::YES_NO, vector<MsgboxButton>() = { buttonVec[2], buttonVec[3] } },
    { MsgboxType::INFO, vector<MsgboxButton>() = { buttonVec[0] } },
    { MsgboxType::WARNING, vector<MsgboxButton>() = { buttonVec[0] } },
    { MsgboxType::ERR, vector<MsgboxButton>() = { buttonVec[0] } }
};
Επεξ/σία από Kercyn
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Γιατί μου φαίνεται λίγο overkill να φτιάξω καινούριες κλάσεις για μια τόσο μικρή διαφοροποίηση. Απλώς επειδή μου φαίνεται ότι δεν είναι εύκολα επεκτάσιμο αυτό που έχω κάνει σκέφτηκα μήπως γίνεται αυτό που έλεγα. Όσο για το MessageBox::ShowInfo κλπ, θα φτιάξω messagebox manager μόλις τελειώσω με τα messageboxes. Ευχαριστώ πολύ.

Overkill οι κλασουλες;
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Αυτό που θέλω να κάνω είναι να παίρνω συγκεκριμένα στοιχεία (πχ το 1ο το 3ο και το 5ο) από το buttonVec και να τα βάζω στο υπο-vector του buttonDesc.

Αυτό που κάνω τώρα είναι να παίρνω ένα range από στοιχεία με iterators (πχ 1ο - 3ο).

 

Αυτό είναι κατανοητό. Η ερώτησή μου ήταν "και για ποιό λόγο τα βάζεις ντε και καλά σε vector".

 

Σκέφτηκες π.χ. ότι εφόσον τα predefined κουμπιά είναι λίγα (ας πούμε άνετα < 20) θα μπορούσες να χρησιμοποιήσεις ένα bitmask γι' αυτή τη δουλειά; Αφού έτσι κι αλλιώς χρησιμοποιείς το MsgboxButtonID σαν αναγνωριστικό του κάθε τυποποιημένου κουμπιού, θα μπορούσες απλά να επιλέξεις τις τιμές του όχι αυξητικά αλλά σα δυνάμεις του 2 οπότε μετά μπορείς να πεις

 

map<MsgboxType, vector<MsgboxButton>> wMessageBox::buttonDesc = {

    { MsgboxType::OK_CANCEL, MsgboxButtonID::OK | MsgboxButtonID::CANCEL },

};

 

και να κάνεις τη δουλειά έτσι. Το συγκεκριμένο δε θα κάνει νομίζω compile γιατί την έχεις δηλωμένη σαν enum class αλλά καταλαβαίνεις την ιδέα.

  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

  • Moderators

Ααα, αυτό είναι κάτι που δεν είχα σκεφτεί. Θα το κοιτάξω και πιθανόν να το αλλάξω σ' αυτό που λες.

 

 

Αν έχεις χρόνο και όρεξη to fool around, που λένε και στο χωριό μου, τσέκαρε το decorator pattern.

 

Πάντα μ' αρέσει να βλέπω καινούρια πράγματα :D

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

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

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

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

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

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

Σύνδεση

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

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