15

私は worm_sim シミュレーター、ubuntu、gcc、codeblocks IDE に取り組んでいます

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

値 packet_generating_rate は const ではありませんが、直接または set 関数を使用して変更しようとすると、エラーが発生します

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

他のファイルでは問題なく使用されていますが、何か提案があれば plz

4

4 に答える 4

28
bool Traffic_source::can_send(void) const

他の人がすでに指摘しているように、問題はconst関数内(行の最後const)でオブジェクトのメンバーを変更できないことです。事実上、メンバー関数は次のようなものに変換されます: bool Traffic_source__can_send( const Traffic_source* this, void )this引数はへのポインターconstです。これは、関数のコンテキスト内にあるpacket_generating_rate ことを意味します。 const

ここで従うことができる 3 つの代替手段があります。

  • メンバーを変更しないでください
  • 関数をマークしないでくださいconst
  • 作るpacket_generating_rate mutable

最初の 2 つのオプションは一般的なものです。関数がオブジェクトを変更するか、const変更しないか、オブジェクトを変更できないかのいずれかconstです。ただし、メンバー ポインター内のメンバーを変更したい場合があります。constその場合、メンバー宣言をマークして、メンバー関数mutable内で変更を有効にすることができます。const

ただし、一般にこれは、メンバー変数がオブジェクトの可視状態に関与しない場合に行われることに注意してください。たとえば、mutex変数はゲッターから返された値やオブジェクトの状態を後で変更しませんが、マルチスレッド環境でオブジェクトの一貫したビューを取得するには、ゲッターがオブジェクトをロック (変更) する必要があります。2 番目の典型的な例はキャッシュです。オブジェクトが計算コストの高い操作を提供する可能性があるため、その操作を実行する関数は結果を後でキャッシュする可能性があります。繰り返しますが、値が再計算されるか、キャッシュから取得されるか同じであるため、オブジェクトの表示状態は変わりません。最後に、既存のインターフェースに準拠するために、構造を悪用する必要がある場合があります。

ここで、3 つのオプションのどれをデザインに適用するかを決めるのはあなた次第です。メンバー属性を変更する必要がある場合は、メンバーが可視状態の一部であり、関数が であってはならないconstか、そうでない場合、オブジェクトの状態の一部ではなく、マークすることができますmutable

于 2012-09-03T13:26:09.007 に答える
4
packet_generating_rate = 0;

定数関数内で使用されます。定数関数では、関数が呼び出されたオブジェクトのデータ メンバーの値を変更することはできません。

于 2012-09-03T12:36:57.207 に答える
3
bool Traffic_source::can_send(void) const

この宣言はthis、へのポインタに変わりますconst。メソッドを としてマークするconstと、インスタンスが不変になるため、そのメンバーを変更できなくなります。

メンバーを変更する場合、なぜconst最初にマークしたのですか?

また、私にcan_sendはゲッターのセマンティクスがあるように見えるので、論理的にはメンバーを変更すべきではありません(ここでのエラーはpacket_generating_rate、メソッドを作成せずに変更しようとしたことだと思いますconst.

于 2012-09-03T12:34:48.257 に答える
0

このような const メンバー関数

bool Traffic_source::can_send(void) const

そのクラスのメンバー変数を変更することは許可されていません。この関数内でメンバー変数を変更すると、エラーが発生するのはこのためです。関数を非 const にすると、このエラーは発生しません。

于 2012-09-03T12:36:22.983 に答える