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
_bool Traffic_source::can_send(void) const
_
他の人がすでに指摘したように、問題はconst
関数(行の最後のconst
)内ではオブジェクトのメンバーを変更できないことです。メンバー関数は実質的に次のようなものに変換されます:bool Traffic_source__can_send( const Traffic_source* this, void )
、ここでthis
引数はconst
へのポインターです。つまり、関数のコンテキストで_packet_generating_rate
_ isconst
になります。
ここで従うことができる3つの選択肢があります。
const
をマークしないでくださいpacket_generating_rate
_ mutable
最初の2つのオプションは一般的なものです。関数はconst
でオブジェクトを変更しないか、またはconst
ではなくオブジェクトを変更できます。ただし、const
メンバーポインター内のメンバーを変更するためにwantを使用する場合があります。その場合、メンバー宣言をmutable
としてマークして、const
メンバー関数内の変更を有効にすることができます。
ただし、これは一般に、メンバー変数がオブジェクトのvisible状態に関与しない場合に行われることに注意してください。たとえば、mutex
変数は、ゲッターから返された値やオブジェクトの状態を後で変更しませんが、マルチスレッド環境でオブジェクトの一貫したビューを取得するには、ゲッターがオブジェクトをロック(変更)する必要があります。 2番目の典型的な例はcacheです。この場合、オブジェクトは計算にコストのかかる操作を提供する可能性があるため、その操作を実行する関数はcacheの結果を後で返す可能性があります。この場合も、値が再計算されるかcacheから取得されるかは同じであるため、オブジェクトの表示状態は変わりません。最後に、既存のインターフェースに準拠するために、構成体を乱用する必要がある場合があります。
ここで、設計に適用する3つのオプションのどれを決定するかはあなた次第です。メンバー属性を変更する必要がある場合、メンバーは可視状態の一部であり、関数はconst
であってはなりません。そうでない場合、オブジェクトの状態の一部ではなく、mutable
とマークできます。
bool Traffic_source::can_send(void) const
この宣言は、this
をconst
へのポインターに変換します。メソッドをconst
としてマークすると、インスタンスが不変になるため、メンバーを変更できません。
メンバーを変更する場合、なぜ最初にconst
とマークしたのですか?
また、私にとっては、can_send
にはゲッターセマンティクスがあるため、論理的にはメンバーを変更するべきではありません(ここでのエラーは、メソッドconst
ではなく、packet_generating_rate
を変更しようとすることです。
packet_generating_rate = 0;
定数関数内で使用されます。定数関数では、関数が呼び出されたオブジェクトのデータメンバーの値を変更することはできません。
このようなconstメンバー関数
bool Traffic_source::can_send(void) const
そのクラスのメンバー変数を変更することはできません。この関数内のメンバー変数を変更すると、エラーが発生します。関数を非constにすると、このエラーは発生しません。