web-dev-qa-db-fra.com

Erreur lors de l'affectation de membre en lecture seule

Je travaille sur WORM_SIM SIMULATER, UBUNTU, GCC, CODEBLOCKS IDE

traffic_source.h Fichier

class Traffic_source : public Buffer_owner, public Connector, public Addressee{
private:
    static unsigned int id_base;
    unsigned int id;
    unsigned int packet_size;
    unsigned int flit_size;
    double packet_generating_rate;
    int pkt_id;
    traffic_source_state ts_state;
    double* packet_to_destination_rate;
    Traffic_mode traffic_mode;
    int period;                // period for packet generation using trace_file
    ifstream trace_file;
    int trace_file_loop_cnt;   // how many times we have gone over the trace file so far
    bool trace_file_empty;
    ofstream trace_dump;       // trace file to dump out

    typedef struct Message {
        int timestamp;
        unsigned int destination;
        unsigned int size;
    } Message, *pMessage;

    Message pre_fetched_message;
    bool get_next_message(Message & msg);

    unsigned int get_destination_uniform(void) const; 
    unsigned int get_destination_transpose1(void) const;
    unsigned int get_destination_transpose2(void) const;
    unsigned int get_destination_hotspot(void) const;
    unsigned int get_destination_customized(void) const;

    void generate_a_packet(unsigned int dst_id);
    void generate_packets(const Message & rec);

public:
    Traffic_source(Position p, int buf_sz);
    ~Traffic_source();
    bool can_send(void) const;
    bool can_receive(void) const { return false; }
    bool send(void);
    bool receive(class Flit * a_flit) { return false; }
    class Connector * get_receiver(void) const; 

    static void reset_id_base(void) { id_base = 0; }

    void tick(void);

    /* traffic control routines */
    void set_packet_generating_rate(double r);
    void set_packet_to_destination_rate(unsigned int dst_id, double rate);
    double get_packet_to_destination_rate(unsigned int dst_id) const;
    double get_total_packet_injection_rate(void) const;
    int set_trace_file(char * file_name);
    bool has_trace_file(void) { return (trace_file.is_open()); }
    int get_id(void) const { return id; }
};

traffic_source.cpp

Traffic_source::Traffic_source(Position p, int buf_sz) : Buffer_owner(buf_sz), Addressee(p) {
    id = id_base ++;
    packet_generating_rate = param.packet_generating_rate;
    packet_size = param.flits_per_packet;
    flit_size = param.flit_size;
    traffic_mode = param.traffic_mode;
    period = 0;
    packet_to_destination_rate = 0;
    pkt_id = 0;
    ts_state = OFF_

    if (param.dump_traffic_source_trace) {
        char file_name[20];
        sprintf(file_name, "%d.trace", id);
        trace_dump.open(file_name);
        if (!trace_dump.is_open() || !trace_dump.good()) {
            cerr << "Error in opening file " << file_name << " for trace dumping" << endl;
            exit(-1);
        }
        trace_dump << "PERIOD\t" << param.simulation_length << endl;
        trace_dump << "#Trace file dumped by worm_sim from node " << id << endl;
        trace_dump << "#Folloing lines are with format as:" << endl
                   << "#timestamp\t" << "destination\t" << "message_size(bits):" << endl;
    }
}

bool Traffic_source::can_send(void) const
{
    int router_id=get_id();
    unsigned int local_availability;

    pRouter a_router= param.network->get_router(router_id);
    local_availability=a_router->get_port_availability(0);
    //cout<<local_availability<<endl;
    if (buffer.is_empty())
        return false;
    if(local_availability <= 0)
    {
        packet_generating_rate = 0; //error: assignment of member ‘Traffic_source::packet_generating_rate’ in read-only object|
        set_packet_generating_rate(0); // error: passing ‘const Traffic_source’ as ‘this’ argument of ‘void Traffic_source::set_packet_generating_rate(double)’ discards qualifiers [-fpermissive]|
        return false;
    }


    // This is somehow trick, we need to verify whether the first flit in the fifo
    // is received right in this clock cycle. If so, we can not send it
    const Flit * first_flit = buffer.peek_flit();
    if (first_flit->arrived_in_this_cycle())
        return false;

    pConnector receiver = get_receiver();

    if (receiver)
        return receiver->can_receive();
    else
        return false;
}

la valeur Packet_Generatining_Rate n'est pas Const, mais lorsque j'essaie de le modifier directement ou à l'aide de la fonction définie, cela me donne des erreurs.

packet_generating_rate = 0; //error: assignment of member    
 ‘Traffic_source::packet_generating_rate’ in read-only object|

set_packet_generating_rate(0); // error: passing ‘const Traffic_source’ as ‘this’ argument of ‘void Traffic_source::set_packet_generating_rate(double)’ discards qualifiers [-fpermissive]|

bien qu'il soit utilisé sur d'autres fichiers sans problème, toute suggestion PLZ

11
user1643699
bool Traffic_source::can_send(void) const

Comme les autres ont déjà signalé, le problème est que dans une fonction const (dernier const dans la ligne), vous ne pouvez pas modifier les membres de l'objet. Effectivement la fonction de membre est traduite dans quelque chose de similaire à: bool Traffic_source__can_send( const Traffic_source* this, void ), l'argument this est un pointeur sur const. Ce qui signifie que packet_generating_rateestconst dans le contexte de la fonction.

Il y a trois alternatives que vous pouvez suivre ici:

  • ne modifiez pas le membre
  • ne marquez pas la fonction const
  • faire packet_generating_ratemutable

Les deux premières options sont les différentes options: la fonction est const et ne modifie pas l'objet, ni ne modifie pas const et peut modifier l'objet. Il y a cependant des cas où vous voulez Pour modifier un membre dans un pointeur de membre const. Dans ce cas, vous pouvez marquer la déclaration de membre comme mutable pour activer la modification à l'intérieur const fonctions membres.

Notez toutefois que, en général, cela se fait lorsque la variable de membre ne participe pas à l'état visible de l'objet. Par exemple, une variable de mutex ne change pas la valeur renvoyée à partir d'un getter ou de l'état de l'objet, mais les getters doivent verrouiller (modifier) ​​l'objet pour obtenir une vue cohérente de l'objet dans les environnements multiples. Le deuxième exemple typique est un cache, où un objet peut offrir une opération coûteuse à calculer, de sorte que la fonction effectuant cette opération pourrait cache le résultat ultérieur. Encore une fois, si la valeur est recalculée ou extraite du cache Il sera identique, de sorte que l'état visible de l'objet ne change pas. Enfin, parfois, vous devrez peut-être abuser de la construction pour être conforme à une interface existante.

Maintenant, il vous appartient de déterminer laquelle des trois options à appliquer à votre conception. Si vous devez modifier l'attribut membre, le membre fait partie de l'état visible et la fonction ne doit pas être const, sinon il ne fait pas partie de l'état de l'objet et peut être marqué mutable.

bool Traffic_source::can_send(void) const

ces déclarations devient this dans un pointeur sur un const. Marquage d'une méthode comme const rend l'instance immuable, vous ne pouvez donc pas modifier ses membres.

Pourquoi l'avez-vous marqué comme const en premier lieu, si vous voulez modifier les membres?

Aussi, pour moi, il semble que can_send a la sémantique getter, de sorte que logiquement, cela ne devrait pas modifier les membres (je pense que l'erreur est que vous essayez de modifier packet_generating_rate, ne pas faire la méthode const.

3
Luchian Grigore
packet_generating_rate = 0;

Il est utilisé à l'intérieur d'une fonction constante. En fonction constante, vous ne pouvez pas modifier la valeur d'un membre de données de l'objet, sur lequel la fonction a été appelée.

3
Coding Mash

Une fonction de membre de const telle que celle-ci

bool Traffic_source::can_send(void) const

est interdit de modifier toutes les variables des membres de cette classe. Lorsque vous modifiez une variable de membre dans cette fonction, c'est pourquoi vous obtenez l'erreur. Faites la fonction non-const et votre erreur ne recevra pas cette erreur.

0
mathematician1975