当前位置: 首页 > 知识库问答 >
问题:

无法访问C std::集中对象的非const成员函数

袁青青
2023-03-14

Message是我制作的一个类。我在传递给messageTimeOut的主函数中有一组它们(以及一些其他函数)。在messageTimeOut中,我使用一个编辑器遍历它们并访问不同的成员函数。然而,我只能访问迭代器指向的消息的const成员函数。如果尝试访问非常量成员函数,则会出现以下错误:

"在函数`ulvMessageTimeOut(threadParameters*)':main.cpp:74: 33:错误:将`const Message'传递为`ulvMessage::setTimedOut(bool)'的`this'参数会丢弃限定符[-fpermissive]。"

我无法访问const Message对象的非const成员函数是有道理的,但是我如何将其设为非const Message对象,以便我可以访问非const成员函数并更改Message?谢谢

我的部分代码:

     [ . . . ]

void messageTimeOut( threadParameters* params )
{
     html" target="_blank">set<Message>::iterator it = params->messages->begin();
     [ . . . ]
    for ( ; it != params->messages->end(); ++it )
    {
        if ( (it->createdTime() + RESPONSE_WAIT) < GetTickCount() ) 
        {
            it->setTimedOut(true); // error 
        }
    }
    ReleaseMutex(sentQueueMutex);
}

     [ . . . ]

int main()
{
    threadParameters rmparameters;
    set<Message> sentMessages;
     [ . . . ]


    rmparameters.logFile = &logFile;
    rmparameters.socket = socketDesciptor;
    rmparameters.messages = &sentMessages;
      [ . . . ]

    messageTimeOut( rmparameters );
      [ . . . ]

    return 0;
}

共有3个答案

汪深
2023-03-14

集合中的对象是const,这意味着它们是不可变的。以下是一些选项

1) Create copies of the messages in a new set
2) Remove the messages, mutate them, and put them back.
3) Remove the "timeout" field from the message.

其中我更喜欢3号。您试图改变消息的事实是一种“糟糕的代码气味”。如果要避免所有数据更改,而是创建一个新的结构(例如std::map),那么可以减少线程同步量。

安博文
2023-03-14

您应该不能修改std::集合的内容。下面是一个简化的测试用例:

#include <set>
#include <iostream>

void print(int & data) {}

int main() {
    std::set<int> objects;

    objects.insert(3);
    print(*objects.find(3));
}

Clang将报告以下错误:

blah.cc:14:2: error: no matching function for call to 'print'
        print(*objects.find(3));
        ^~~~~
blah.cc:4:6: note: candidate function not viable: 1st argument ('const int') would lose const qualifier
void print(int & data) {
     ^

因此,在这里使用集合似乎不是正确的决策。

昝卓
2023-03-14

你不能。

std::集中的元素总是常量,因为否则用户可以通过修改属于该集的元素来修改集中的顺序。

请注意,调用的函数不改变顺序并不重要,因为std::set无法检查这一点。

解决此问题的常见方法是从集合中删除元素,修改它,然后重新插入它。另一种方法是使用地图,即使这可能会迫使您复制一些数据。

 类似资料:
  • 我们一直强调,最低权限原则(principle of least privilege)是良好软件工程的最基本原则之一。下面介绍这个原则如何应用于对象。 有些对象需要修改,有些不需要。程序员可以用关键字const指定对象不能修改,且修改时会产生语法错误。例如: const Time noon(12,0,0); 声明 Time 类对象 noon 为 const,并将其初始化为中午12时。 软件工程视点

  • 问题内容: 因此,我正在重构代码以实现更多的OOP。我设置了一个类来保存页面属性。 稍后,我像这样调用set_page_title()函数 当我收到错误消息时: 调用非对象上的成员函数set_page_title() 那我想念什么呢? 问题答案: 这意味着它不是对象的实例。我们可以看到您用来初始化变量的代码吗? 当您期望特定的对象类型时,还可以使用PHP的类型提示功能 Docs 在违反逻辑时得到错

  • 问题内容: 我的查询有问题。我最近改用了PDO,这对我来说是新的。现在,我需要在查询中使用JOIN来从另一个表中获取数据,而无需执行两次执行。 问题是,我收到此错误: 我不明白问题是什么。这是我的代码的样子: 或简称为查询: 我想要的是,从用户ID为session且请求为0的朋友那里获取所有行。但是然后我想获取用户中那些朋友的ID,以便我可以链接到他们的个人资料。注意 感谢您提供任何反馈意见,不必

  • 在g中运行下面的代码将导致以下错误: 错误:将“const A”传递为“this”参数会丢弃限定符[-fpermissive] 我们在哪里使用? F允许意味着代码不一致。标准在哪里规定这是一个错误?

  • 我遇到了我不明白的情况。有人能很好地解释为什么第一个代码编译正确,而第二个代码出错: 错误:“TestClass::z”的值在常量表达式中不可用。} - ^ 注意:“int TestClass::z”不是const static int z;" 工作代码: 但是当我尝试使 静态时,我得到上述错误: 附言:我正在使用mingw32-g 4.8.1

  • 请帮帮我 致命错误:在第104行的/home/u357965800/public_html/include/class.admin.php中对非对象调用成员函数prepare()