【问题标题】:C++ Setting member object which has const memberC++设置具有const成员的成员对象
【发布时间】:2016-09-07 08:28:04
【问题描述】:

我正在使用 OIS 来处理我与 Ogre 的输入,目前,在 KeyPress/Release 上,将在订阅者之间构建和分发如下所示的消息对象。

class Message
{
public:
    Message();
    ~Message();

    inline void SetKeyEvent(const OIS::KeyEvent& keyEvent) { _keyEvent = keyEvent; }

    const OIS::KeyEvent& GetKeyEvent() const { return _keyEvent; }

private:

    OIS::KeyEvent _keyEvent;

};

由于每当通过键盘接收输入时都会构造/销毁此对象,因此我尝试存储一个预先构造的 Message 对象,然后在分发之前使用新数据简单地更新 _keyEvent 字段。

问题是OIS::KeyEvent 对象有一个 const 成员,这使我无法使用赋值运算符。 SetKeyEvent 方法给了我以下语法错误:

function "OIS::KeyEvent::operator=(const OIS::KeyEvent &)" (declared implicitly) cannot be referenced -- it is a deleted function

我想知道实现此功能的最佳方法是什么?

提前致谢

编辑:为了澄清,我已经尽可能使用初始化列表。我的意图是预先构建 Message 对象,然后使用 SetKeyEvent 方法使用 OIS 触发的 KeyPress 事件中的新事件数据更新 _keyEvent 字段。我想知道这是否可行,如果可行,最好的方法是什么。

【问题讨论】:

  • 这与 const 成员无关。这意味着OIS::KeyEvent 没有赋值运算符。
  • @Hayt 它没有默认赋值运算符因为里面有一个 const 成员。
  • 你是对的。我完全没有以某种方式建立这种联系。
  • 您真的需要存储预先构建的消息吗?它还有其他成员吗?

标签: c++ constants ogre


【解决方案1】:

复制操作符被删除,所以你必须使用指针。

class Message
{
public:
    Message();
    ~Message();

    inline void SetKeyEvent(OIS::KeyEvent* keyEvent) { _keyEvent = keyEvent; }

    const OIS::KeyEvent& GetKeyEvent() const { return _keyEvent; }

private:

    OIS::KeyEvent* _keyEvent;

};

现在最好检查一下 setter 中的参数是否不是 nullptr。

inline void SetKeyEvent(OIS::KeyEvent* keyEvent) 
{
   assert(keyEvent != nullptr);
   _keyEvent = keyEvent; 
}

assert() 需要#include <assert.h>

编辑:

抱歉,忘记了getter方法。你也必须使用指针。

const OIS::KeyEvent* keyEvent = &Message.GetKeyEvent();

Message 是您的类实例。

【讨论】:

  • 不要这样做。使用构造函数correctly,仅此而已。
  • 调用getter且没有构造函数调用时抛出错误信息。
  • 什么错误信息?如果您对 getter 有任何疑问,请提出。
  • 问题中有错误信息:function "OIS::KeyEvent::operator=(const OIS::KeyEvent &)"(隐式声明)不能被引用——它是一个被删除的函数
  • 可以,因为OIS::KeyEvent中的赋值运算符被删除了,他不能使用了。
【解决方案2】:

可以通过使用placement new 和显式的析构函数调用来实现,这是你通常不应该做的事情:

 inline void SetKeyEvent(const OIS::KeyEvent& keyEvent) 
 { 
     _keyEvent.~KeyEvent();
     new (&_keyEvent) OIS::KeyEvent(keyEvent);
 }

这是糟糕的丑陋可怕的代码,使用风险自负。

【讨论】:

    猜你喜欢
    • 2021-05-20
    • 2012-03-02
    • 2013-06-07
    • 2021-07-25
    • 1970-01-01
    • 2017-02-10
    • 1970-01-01
    • 1970-01-01
    • 2011-12-28
    相关资源
    最近更新 更多