C++ 在只读对象中分配成员时出错
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12247970/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Error in assignment of member in read-only object
提问by user1643699
I am working on worm_sim simulater , ubuntu, gcc, codeblocks IDE
我正在研究 worm_sim 模拟器、ubuntu、gcc、codeblocks IDE
traffic_source.h file
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
流量源.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;
}
the value packet_generating_rate is not const but when i try to modify it either directly or using the set function it give me errors
值 packet_generating_rate 不是常量,但是当我尝试直接修改它或使用 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]|
although it is used on other files with no problem, any suggestion plz
虽然它在其他文件上使用没有问题,但请提出任何建议
回答by David Rodríguez - dribeas
bool Traffic_source::can_send(void) const
As other's have already pointed out, the problem is that inside a const
function (last const
in the line) you cannot modify the members of the object. Effectively the member function is translated into something similar to: bool Traffic_source__can_send( const Traffic_source* this, void )
, there the this
argument is a pointer to const
. Which in turn means that packet_generating_rate
isconst
in the context of the function.
正如其他人已经指出的那样,问题是在const
函数内部(最后const
一行)你不能修改对象的成员。实际上,成员函数被翻译成类似于:bool Traffic_source__can_send( const Traffic_source* this, void )
, this
参数是指向 的指针const
。这反过来意味着这packet_generating_rate
是const
在函数的上下文中。
There are three alternatives that you can follow here:
您可以在此处遵循三种选择:
- don't modify the member
- don't mark the function
const
- make
packet_generating_rate
mutable
- 不要修改成员
- 不要标记函数
const
- 制作
packet_generating_rate
mutable
The first two options are the common ones: either the function is const
and does not modify the object, or it is not const
and can modify the object. There are cases however, where you wantto modify a member within a const
member pointer. In that case you can mark the member declaration as mutable
to enable modification inside const
member functions.
前两个选项是通用的:要么函数是const
并且不修改对象,要么不是const
并且可以修改对象。但是,在某些情况下,您希望修改const
成员指针内的成员。在这种情况下,您可以将成员声明标记为mutable
启用const
成员函数内部的修改。
Note however that in general this is done when the member variable does not take part on the visiblestate of the object. For example a mutex
variable does not change the value returned from a getter or the state of the object afterwards, but getters need to lock (modify) the object to obtain a consistent view of the object in multithreaded environments. The second typical example is a cache, where an object may offer an operation that is expensive to calculate, so the function performing that operation might cachethe result for later. Again, whether the value is recalculated or retrieved from the cacheit will be the same, so the visible state of the object does not change. Finally, sometimes you might need to abuse the construct to conform to an existing interface.
但是请注意,通常这是在成员变量不参与对象的可见状态时完成的。例如,mutex
变量不会更改从 getter 返回的值或此后对象的状态,但 getter 需要锁定(修改)对象以获得多线程环境中对象的一致视图。第二个典型示例是cache,其中对象可能提供计算成本高的操作,因此执行该操作的函数可能会缓存结果以备后用。再次,该值是重新计算还是从缓存中检索它将是相同的,因此对象的可见状态不会改变。最后,有时您可能需要滥用构造以符合现有接口。
Now it is up to you to determine which of the three options to apply to your design. If you need to modify the member attribute, then either the member is part of the visible state and the function should not be const
, or else it is not part of the state of the object and can be marked mutable
.
现在由您决定将三个选项中的哪一个应用于您的设计。如果需要修改成员属性,那么要么该成员是可见状态的一部分,函数不应是const
,要么不是对象状态的一部分,可以标记mutable
。
回答by Luchian Grigore
bool Traffic_source::can_send(void) const
this declarations turns this
into a pointer to a const
. Marking a method as const
makes the instance immutable, so you can't modify its members.
this 声明变成this
了一个指向 a 的指针const
。将方法标记为const
使实例不可变,因此您无法修改其成员。
Why did you mark it as const
in the first place, if you're going to modify members?
const
如果要修改成员,为什么首先将其标记为?
Also, to me it seems that can_send
has getter semantics, so logically it shouldn't modify members (I think the error here is that you attempt to modify packet_generating_rate
, not making the method const
.
另外,对我来说,它似乎can_send
具有 getter 语义,因此从逻辑上讲它不应该修改成员(我认为这里的错误是您尝试修改packet_generating_rate
,而不是将方法const
.
回答by Coding Mash
packet_generating_rate = 0;
It is used inside a constant function. In constant function, you cannot change the value of any data member of the object, on which the function was called.
它在常量函数中使用。在常量函数中,您不能更改调用该函数的对象的任何数据成员的值。
回答by mathematician1975
A const member function such as this
像这样的 const 成员函数
bool Traffic_source::can_send(void) const
is disallowed from modifying any member variables of that class. As you modify a member variable inside this function, this is why you get the error. Make the function non-const and your will not get this error.
不允许修改该类的任何成员变量。当您修改此函数内的成员变量时,这就是您收到错误的原因。使函数非常量,您将不会收到此错误。