Error assignment of member in read only object

I am working on worm_sim simulater , ubuntu, gcc, codeblocks IDE traffic_source.h file class Traffic_source : public Buffer_owner, public Connector, public Addressee{ private: static unsigned...

I am working on worm_sim simulater , ubuntu, gcc, codeblocks IDE

traffic_source.h file

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 << "PERIODt" << 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
                   << "#timestampt" << "destinationt" << "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 = 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

IDEONE: http://ideone.com/uSqSq7

#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
using namespace std;

struct node
{
    int value, position;
    bool left, right;
    bool operator < (const node& a) const
    {
        return value < a.value;
    }
};

int main()
{
    int n;
    cin >> n;

    vector < node > a(n);
    set < node > s;

    for (auto &i: a)
    {
        cin >> i.value;
        i.left=i.right=0;
    }

    a[0].position=1;
    s.insert(a[0]);

    for (int i=1; i<n; i++)
    {
        auto it=s.upper_bound(a[i]);
        auto it2=it; --it2;
        if (it==s.begin())
        {
            a[i].position=2*it->position;
            s.insert(a[i]);
            it->left=1;
        }
        else if (it==s.end())
        {
            a[i].position=2*(--it)->position+1;
            s.insert(a[i]);
            it->right=1;
        }
        else
        {
            if (it2->right==0)
            {
                a[i].position=2*it2->position+1;
                s.insert(a[i]);
                it2->right=1;
            }
            else
            {
                a[i].position=2*it->position;
                s.insert(a[i]);
                it->left=1;
            }
        }
    }

    for (auto i: a) cout << i.position << ' ';
}

When I compile this code, I get

error: assignment of member ‘node::right’ in read-only object

I think this has something to do with the const in bool operator <, but I cannot get rid of it as it is necessary to create the set.

hanshenrik's user avatar

hanshenrik

18.9k3 gold badges41 silver badges82 bronze badges

asked Feb 10, 2016 at 12:30

anukul's user avatar

7

Angelika Langer once wrote a piece about this: Are Set Iterators Mutable or Immutable?.

You can solve this by defining the Node members immaterial for the set ordering as mutable:

mutable bool left, right;

(see a building version in ideone.)

Personally, I would consider a design mapping the immutable part to mutable parts using a map.

anukul's user avatar

anukul

1,9011 gold badge19 silver badges36 bronze badges

answered Feb 10, 2016 at 12:50

Ami Tavory's user avatar

Ami TavoryAmi Tavory

73.3k10 gold badges138 silver badges178 bronze badges

0

Problem:

Remember that keys in a std::set are constant. You can’t change a key after it’s inserted into the set. So when you dereference the iterator, it necessarily returns a constant reference.

const node& n = (*it);
n->left = 1; //It will not allow you to change as n is const &.

Solution:

As Ami Tavory answered, you can declare left and right as mutable.

answered Feb 10, 2016 at 13:32

CreativeMind's user avatar

tohtarov_ufa

0 / 0 / 0

Регистрация: 13.01.2015

Сообщений: 137

1

01.06.2015, 06:58. Показов 3130. Ответов 4

Метки нет (Все метки)


Добрый день!
У меня есть класс Delegate, в нем указатель на виджет m_editor
.h файл:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Delegate : public QStyledItemDelegate
{
public:
    Delegate (QObject* parent = 0);
    QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option,
                          const QModelIndex& index) const Q_DECL_OVERRIDE;
 
    void setEditorData(QWidget* editor, const QModelIndex& index) const Q_DECL_OVERRIDE;
    void setModelData(QWidget* editor, QAbstractItemModel* model,
                      const QModelIndex& index) const Q_DECL_OVERRIDE;
 
    void updateEditorGeometry(QWidget* editor,
                              const QStyleOptionViewItem& option, const QModelIndex& index) const Q_DECL_OVERRIDE;
    void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
 
private:
    QGraphicsView* m_editor = nullptr;
 
};

функция в .cpp файле

C++ (Qt)
1
2
3
4
5
6
7
QWidget* Delegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &/* option */,
const QModelIndex & index ) const
{
    m_editor = new QGraphicsView(parent);
...
}

Почему то выдает ошибку
/home/user/KVideoClient/delegate.cpp:18: error: assignment of member ‘Delegate::m_editor’ in read-only object
m_editor = new QGraphicsView(parent);

что для меня лично не понятно

Спасибо за помощь!

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



1442 / 1323 / 131

Регистрация: 20.03.2009

Сообщений: 4,689

Записей в блоге: 11

01.06.2015, 07:52

2

не зная броду, не суйся в воду
Delegate::createEditor(QWidget *parent, const QStyleOptionViewItem &/* option */, const QModelIndex & index ) const вот эта хрень для чего тут?



0



0 / 0 / 0

Регистрация: 13.01.2015

Сообщений: 137

01.06.2015, 11:57

 [ТС]

3

для того, что это переопределенная функция и без const она вообще не отрабатывает.
почему не отрабатывает — не знаю.



0



1442 / 1323 / 131

Регистрация: 20.03.2009

Сообщений: 4,689

Записей в блоге: 11

01.06.2015, 17:37

4



0



Псевдослучайный

1946 / 1145 / 98

Регистрация: 13.09.2011

Сообщений: 3,215

01.06.2015, 18:00

5

Лучший ответ Сообщение было отмечено tohtarov_ufa как решение

Решение

Цитата
Сообщение от tohtarov_ufa
Посмотреть сообщение

для того, что это переопределенная функция и без const она вообще не отрабатывает.

Ну ещё бы, ведь это будет уже совсем другой метод, а не перегрузка нужного.
createEditor() своей по логике ничего не должна менять в данных делегата, ибо тот только описывает интерфейс взаимодействия с моделями и один экземпляр может одновременно отвечать даже не только за разные записи в одной модели, но и за разные модели вообще.



1



IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

01.06.2015, 18:00

5

IDEONE: http://ideone.com/uSqSq7

#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
using namespace std;

struct node
{
int value, position;
bool left, right;
bool operator < (const node& a) const
{
return value < a.value;
}
};

int main()
{
int n;
cin >> n;

vector < node > a(n);
set < node > s;

for (auto &i: a)
{
cin >> i.value;
i.left=i.right=0;
}

a[0].position=1;
s.insert(a[0]);

for (int i=1; i<n; i++)
{
auto it=s.upper_bound(a[i]);
auto it2=it; --it2;
if (it==s.begin())
{
a[i].position=2*it->position;
s.insert(a[i]);
it->left=1;
}
else if (it==s.end())
{
a[i].position=2*(--it)->position+1;
s.insert(a[i]);
it->right=1;
}
else
{
if (it2->right==0)
{
a[i].position=2*it2->position+1;
s.insert(a[i]);
it2->right=1;
}
else
{
a[i].position=2*it->position;
s.insert(a[i]);
it->left=1;
}
}
}

for (auto i: a) cout << i.position << ' ';
}

Когда я компилирую этот код, я получаю

error: assignment of member ‘node::right’ in read-only object

Я думаю, что это как-то связано с const в bool operator <, но я не могу от этого избавиться, так как нужно создавать набор.

2

Решение

Другие решения

Проблема:

Помните, что ключи в std :: set являются постоянными. Вы не можете изменить ключ после того, как он вставлен в набор. Поэтому, когда вы разыменовываете итератор, он обязательно возвращает постоянную ссылку.

const node& n = (*it);
n->left = 1; //It will not allow you to change as n is const &.

Решение:

Как ответила Ами Тавори, вы можете объявить левую и правую изменяемыми.

0

  1. 07-17-2020


    #1

    VeeDub is offline


    Registered User


    Error: assignment of i_value in read-only object

    Hello,

    I have two programs that to the best of my knowledge use the same data structures and contain the same statements.

    One program works and the other fails with the error in the title. No doubt there is a reason, but at this stage it is not clear to me.

    Please refer to the two attachments:

    1. Example_Data_Structure
    2. Linked_List_Example

    Example_Data_Structure is a short program that builds and executes as I would expect.

    Example_Data_Structure contains an extract of code from Linked_List_Example.

    For some reason the code works fine in isolation, but not when combined with the other statements.

    It’s a mystery to me.

    Linked_List_Example, contains a lot more code (sorry), but also contains the same code as in Example_Data_Structure. I’ve had to include the whole program because obviously there is something in it which causes the following statement to fail.

    Code:

    record->i_value = 100;

    For reason;

    Code:

    162|error: assignment of member �i_value� in read-only object|

    For some reason I can’t upload the other program. No errors but it doesn’t appear in the Attachment Manager.

    Also the Attachment Manager states that uploaded programs are supposedly deleted after 1 hour; but my upload from yesterday is still there?


  2. 07-17-2020


    #2

    VeeDub is offline


    Registered User


    I don’t have access to Attachments in ‘My Settings’ ?


  3. 07-17-2020


    #3

    Salem is offline


    and the hat of int overfl

    Salem's Avatar


    Example_Data_Structure.c seems fine to me.

    Code:

    $ gcc -Wall Example_Data_Structure.c 
    $ ./a.out 
    Record - detail: some string
    Record - value:  100


  4. 07-17-2020


    #4

    VeeDub is offline


    Registered User


    Quote Originally Posted by Salem
    View Post

    It seems fine to me.

    Yes it is, the issue is that the same code in the other example doesn’t work.

    I’m assuming that the issue must be due to some of the other statements I have in the 2nd program; it is not at all clear to me why the error is occurring.

    So I need to upload the other example so that I can get an informed opinion.

    The attachment manager seems buggy to me. It always seems to take multiple attempts to get an attachment to upload / appear; and I’ve not managed to upload the 2nd program at all??


  5. 07-17-2020


    #5

    VeeDub is offline


    Registered User


    Finally managed to upload the 2nd attachment


  6. 07-17-2020


    #6

    Salem is offline


    and the hat of int overfl

    Salem's Avatar


    Well the big problem is you’re missing a brace at the end of the else in add_record()
    Error: assignment of i_value in read-only object-missing-brace-png

    Then

    Code:

    foo.c: In function �add_key�:
    foo.c:54:22: warning: assignment discards �const� qualifier from pointer target type [-Wdiscarded-qualifiers]
             current->key = key;
                          ^
    foo.c:73:28: warning: assignment discards �const� qualifier from pointer target type [-Wdiscarded-qualifiers]
             current->next->key = key;
                                ^

    Use strcpy to copy things.

    Code:

    foo.c: In function �add_record�:
    foo.c:89:9: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
             if (current->record_list = NULL) {
             ^
    foo.c:121:13: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
                 if (current->record_list = NULL) {
                 ^

    You probably meant to use ==

    There’s no reason to cast the return result of malloc.
    > record_list =

    (record_t *) malloc(sizeof(record_t));
    Casting malloc — Cprogramming.com


  7. 07-17-2020


    #7

    VeeDub is offline


    Registered User


    Quote Originally Posted by Salem
    View Post

    There’s no reason to cast the return result of malloc.
    > record_list = (record_t *) malloc(sizeof(record_t));
    Casting malloc — Cprogramming.com

    Appreciate your reply, I must admit I have been programming on my laptop and with the smaller screen I was having trouble seeing the whole function. I should have used the «-» minus key to condense the code blocks to make sure that I had all the brackets matched up.

    I’m afraid I don’t understand your last comment regarding casting malloc.

    Unfortunately I’m none the wiser, even after reading the included link.

    My understanding is that each time I add a new «record» in the list. I need to allocate memory for that record.

    And the statement

    Code:

    record_list= (record_t*) ...

    is the statement required to allocate the memory for the next record/structure in the list, before then populating the fields in the record.

    Can you show the statement that I should be using instead?


  8. 07-18-2020


    #8

    Salem is offline


    and the hat of int overfl

    Salem's Avatar


    I mean you should be able to do this without upsetting the compiler.

    Code:

    record_list = malloc(sizeof(record_t));

    The cast would cover up the mistake of not including stdlib.h

    If you get a message along the lines of ‘cannot convert void* to type*’, then that means you’re using C++ to compile your C program.
    This is something you shouldn’t be doing either.


  9. 07-18-2020


    #9

    VeeDub is offline


    Registered User


    Quote Originally Posted by Salem
    View Post

    The cast would cover up the mistake of not including stdlib.h

    If you get a message along the lines of ‘cannot convert void* to type*’, then that means you’re using C++ to compile your C program.
    This is something you shouldn’t be doing either.

    The includes that are specified are:

    Code:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    The compile options that I’m using are:

    Code:

    -------------- Build: Debug in Linked_List_example_with_Data_Structure_II (compiler: GNU GCC Compiler)---------------
    gcc -Wall -g  -c /home/dev/c/learn/Linked_List_example_with_Data_Structure_II/main.c -o obj/Debug/main.o
    gcc  -o bin/Debug/Linked_List_example_with_Data_Structure_II obj/Debug/main.o   
    Output file is bin/Debug/Linked_List_example_with_Data_Structure_II with size 10.74 KB
    Process terminated with status 0 (0 minute(s), 0 second(s))
    0 error(s), 0 warning(s) (0 minute(s), 0 second(s))


  10. 07-18-2020


    #10

    VeeDub is offline


    Registered User


    There is still an error in the add_record function.

    Using the debugger I observe that the execution crashes at line 96

    Code:

    strcpy(current->record_list->c_detail1,record->c_detail1);

    Unfortunately this statement looks correct to me.

    I’ve used printf at line 92 & 93 to confirm that the record details (i.e. the «inputs» are correctly set.

    Perhaps the issue is with line 95,

    Code:

    record_list = (record_t *) malloc(sizeof(record_t));

    although I don’t observe any errors when this line is executed

    PS: I had issues uploading the attachment again. Does anybody else have issues with this. I’m using latest version of Chrome on Windows


  11. 07-18-2020


    #11

    Hodor is offline


    misoturbutc

    Hodor's Avatar


    Quote Originally Posted by VeeDub
    View Post

    Code:

    strcpy(current->record_list->c_detail1,record->c_detail1);

    current->record_list is NULL on line 96, as proven by line 89, and then you’re trying to dereference (i.e. you’re effectively trying to do NULL->c_detail1) so it crashes.

    On line 95, where is record_list even declared? Same for line 109… does this compile? Edit: nvm, I see now that it’s a global that is somewhat hidden because it’s indented badly. Why is it global?


  12. 07-18-2020


    #12

    VeeDub is offline


    Registered User


    Quote Originally Posted by Hodor
    View Post

    current->record_list is NULL on line 96, as proven by line 89, and then you’re trying to dereference (i.e. you’re effectively trying to do NULL->c_detail1) so it crashes.

    On line 95, where is record_list even declared? Same for line 109… does this compile? Edit: nvm, I see now that it’s a global that is somewhat hidden because it’s indented badly. Why is it global?

    Hello Hodor,

    My understanding is that line 95

    Code:

    record_list = (record_t *) malloc(sizeof(record_t));

    Allocates memory for a new record, which I then update in lines 96, 97 and 98.

    If I comment line 96

    Code:

    strcpy(current->record_list->c_detail1,record->c_detail1);

    Then line 97 fails

    Code:

    current->record_list->i_value = record->i_value;

    So the issue must be in line 95

    Code:

    record_list = (record_t *) malloc(sizeof(record_t));

    But a similar statement works earlier in the code (line 161) to create a record structure

    Code:

    record = (record_t *) malloc(sizeof(record_t));

    and I successfully update this record in main(); so I don’t understand why line 95 isn’t working.

    As to why the record structure is a global variable. My intention is to access and update the record structure in a number of functions — not just add_record.


  13. 07-18-2020


    #13

    Hodor is offline


    misoturbutc

    Hodor's Avatar


    When your code reaches line 96, what is the value of current->record_list? As far as I can see it’s NULL, because program execution only reaches line 96 if current->record_list is NULL (see line 89; i.e. it’s still NULL when line 96 is reached). You can’t do

    Code:

                strcpy(current->record_list->c_detail1,record->c_detail1);

    Because the part in bold must be NULL otherwise the line would never have been reached because execution only reaches line 96 if the part in bold is NULL (because of line 89).

    Maybe before reaching line 96, and after line 89, you have to do something like

    Code:

    current->record_list = record_list;

    (But don’t quote me on that I haven’t looked very closely at your code because I’m on a device that makes it difficult for me. That said you have to either add something like the line above or change lines 96-98 to use record_list rather than current->record_list or something else that is not NULL)

    Edit: What I’m suggesting is either :

    Code:

            /* Check head of record list */
            if (current->record_list == NULL) {
                /* First record */
    
    //          printf("Record - detail: %sn",record->c_detail1);
    //          printf("Record - value:  %dn",record->i_value);
    
                record_list = (record_t *) malloc(sizeof(record_t));
    current->record_list = record_list;
                strcpy(current->record_list->c_detail1,record->c_detail1);
                current->record_list->i_value = record->i_value;
                current->record_list->next = NULL;
    
            } /* current->record_list == NULL */

    or

    Code:

            /* Check head of record list */
            if (current->record_list == NULL) {
                /* First record */
    
    //          printf("Record - detail: %sn",record->c_detail1);
    //          printf("Record - value:  %dn",record->i_value);
    
                record_list = (record_t *) malloc(sizeof(record_t));
                strcpy(record_list->c_detail1,record->c_detail1);
                record_list->i_value = record->i_value;
                record_list->next = NULL;
    
            }

    Last edited by Hodor; 07-18-2020 at 10:14 PM.


  14. 07-18-2020


    #14

    VeeDub is offline


    Registered User


    Thanks Hodor,

    You’re right of course

    Line 95 should have been

    Code:

    current->record_list = (record_t *) malloc(sizeof(record_t));

    If I keep making enough mistakes I’ll eventually start to learn.

    I just need to get to the point where I can fix them by myself.

    Cheers


  15. 07-18-2020


    #15

    Hodor is offline


    misoturbutc

    Hodor's Avatar


    Quote Originally Posted by VeeDub
    View Post

    Thanks Hodor,

    You’re right of course

    Line 95 should have been

    Code:

    current->record_list = (record_t *) malloc(sizeof(record_t));

    If I keep making enough mistakes I’ll eventually start to learn.

    I just need to get to the point where I can fix them by myself.

    Cheers

    I made an edit while you were replying. Your way in this new post is fine as well, of course


Comments

@UralZima

UralZima

referenced
this issue

Sep 27, 2018

@behlendorf

When zfs_kobj_init() is called with an attr_cnt of 0 only the
kobj->zko_default_attrs is allocated.  It subsequently won't
get freed in zfs_kobj_release since the free is wrapped in
a kobj->zko_attr_count != 0 conditional.

Split the block in zfs_kobj_release() to make sure the
kobj->zko_default_attrs are freed in this case.

Additionally, fix a minor spelling mistake and typo in
zfs_kobj_init() which could also cause a leak but in practice
is almost certain not to fail.

Reviewed-by: Richard Elling <Richard.Elling@RichardElling.com>
Reviewed-by: Tim Chase <tim@chase2k.com>
Reviewed-by: John Gallagher <john.gallagher@delphix.com>
Reviewed-by: Don Brady <don.brady@delphix.com>
Reviewed-by: George Melikov <mail@gmelikov.ru>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #7957

@openzfs
openzfs

locked as too heated and limited conversation to collaborators

Jan 28, 2019

bool Traffic_source::can_send(void) const

Как уже указывали другие, проблема в том, что внутри const функция (последняя const в строке) вы не можете изменять элементы объекта. Фактически функция-член преобразуется во что-то похожее на: bool Traffic_source__can_send( const Traffic_source* this, void ), там this аргумент является указателем на const. Что в свою очередь означает, что packet_generating_rate is const в контексте функции.

Есть три альтернативы, которым вы можете следовать здесь:

  • не изменять член
  • не отмечайте функцию const
  • сделать packet_generating_rate mutable

Первые два варианта являются общими: либо функция const и не изменяет объект, или он не const и может изменять объект. Однако бывают случаи, когда вы хотеть для изменения члена в const указатель члена. В этом случае вы можете пометить объявление члена как mutable чтобы разрешить модификацию внутри const функции-члены.

Обратите внимание, однако, что обычно это делается, когда переменная-член не участвует в видимый состояние объекта. Например mutex переменная не изменяет значение, возвращаемое геттером, или состояние объекта впоследствии, но геттерам необходимо блокировать (модифицировать) объект, чтобы получить согласованное представление объекта в многопоточных средах. Второй типичный пример — кэш, где объект может предлагать операцию, которую сложно вычислить, поэтому функция, выполняющая эту операцию, может кэш результат на потом. Опять же, независимо от того, пересчитывается ли значение или извлекается из кэш это будет то же самое, поэтому видимое состояние объекта не изменится. Наконец, иногда вам может понадобиться злоупотребить конструкцией, чтобы соответствовать существующему интерфейсу.

Теперь вам решать, какой из трех вариантов применить к вашему дизайну. Если вам нужно изменить атрибут члена, то либо член является частью видимого состояния, и функция не должна быть const, либо оно не является частью состояния объекта и может быть помечено mutable.

Понравилась статья? Поделить с друзьями:
  • Error begin was not declared in this scope
  • Error assigning to an array from an initializer list
  • Error assets api is not available мортал комбат мобайл
  • Error battery cannot charge
  • Error assert was not declared in this scope