2012-09-03 23 views
6

estoy trabajando en simulater worm_sim, ubuntu, gcc, bloques de código IDEerror en la asignación del miembro de sólo lectura objeto

archivo traffic_source.h

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

el valor packet_generating_rate no es const pero cuando intento modificarlo directamente o usando la función set me da errores

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

aunque se utiliza en otros archivos sin ningún problema, los PLZ cualquier sugerencia

Respuesta

3
bool Traffic_source::can_send(void) const 

esta declaración se convierte this en un puntero a un const. Marcar un método como const hace que la instancia sea inmutable, por lo que no puede modificar sus miembros.

en primer lugar, ¿por qué lo marcó como const, si va a modificar los miembros?

Además, me parece que tiene una semántica can_send getter, por lo que lógicamente no debe modificar los miembros (creo que el error aquí es que intenta modificar packet_generating_rate, no haciendo el método const.

0

Una const función miembro como este

bool Traffic_source::can_send(void) const 

no está permitida desde la modificación de las variables miembro de esa clase. a medida que modifica una variable miembro dentro de esta función, es por esto que se obtiene el error. Hacer que la función no constante y su voluntad no obtener este error.

2
packet_generating_rate = 0; 

Se utiliza dentro de una función constante. En la función constante, no puede cambiar el valor de ningún miembro de datos del objeto al que se llamó la función.

17
bool Traffic_source::can_send(void) const 

Como otros de que ya han señalado, el problema es que dentro de una función const (última const en la línea) no puede modificar los miembros del objeto. Efectivamente, la función miembro se traduce en algo similar a: bool Traffic_source__can_send(const Traffic_source* this, void), allí el argumento this es un puntero a const. Lo que a su vez significa que packet_generating_rateesconst en el contexto de la función.

existen tres alternativas que puede seguir aquí:

  • no modifique el miembro
  • no marque la función const
  • hacen packet_generating_ratemutable

La primera dos opciones son las comunes: o bien la función es const y no modifica el objeto, o no es const y puede modificar el objeto. Sin embargo, hay casos en los que quiere para modificar un miembro dentro de un puntero de miembro const. En ese caso, puede marcar la declaración de miembro como mutable para habilitar la modificación dentro de las funciones de miembro const.

Sin embargo, tenga en cuenta que, en general, esto se hace cuando la variable miembro no participa en el estado visible del objeto. Por ejemplo, una variable mutex no cambia el valor devuelto por un getter o el estado del objeto después, pero los getters necesitan bloquear (modificar) el objeto para obtener una vista consistente del objeto en entornos multiproceso. El segundo ejemplo típico es un caché , donde un objeto puede ofrecer una operación que es costosa de calcular, por lo que la función que realiza esa operación podría caché el resultado para más adelante. Nuevamente, si el valor se recalcula o recupera del caché , será el mismo, por lo que el estado visible del objeto no cambiará. Finalmente, a veces es posible que necesite abusar de la construcción para cumplir con una interfaz existente.

Ahora depende de usted determinar cuál de las tres opciones se aplicará a su diseño. Si necesita modificar el atributo de miembro, entonces el miembro es parte del estado visible y la función no debe ser const, o si no es parte del estado del objeto y puede marcarse como mutable.

Cuestiones relacionadas