如何在函数声明中使用const

cap*_*ain 1 c++ opencv const reference

在opencv中,我碰巧修改了一个作为常量传递给我的函数的变量:

void someFunction(const cv::Mat matrix)
{
  double value = 5.0;
  matrix /= value;
}
Run Code Online (Sandbox Code Playgroud)

它不仅编译,而且在调用之后矩阵仍然被修改someFunction(matrix),即使我没有matrix作为参考传递.我给这家代码编译的解释是,我没有真正改变的任何成员matrixsomeFunction,但地址的内容由指针所指向datamatrix,但我真的不知道.由于我有点困惑,我尝试在一个小程序中重现这种情况:

#include <iostream>
using namespace std;

class Foo;
{ 
 private:
  int* ptr;

public:
  Foo()
  {
    ptr = new int[1];
    ptr[0] = 1;
  }

  const Foo& operator += ( const Foo& obj) const
  {
    this->ptr[0] += obj.ptr[0];
    return *this;
  }

};

void changeConst(const Foo var)
{
  Foo foo;
  var += foo;
}

int main() 
{
  Foo obj;
  changeConst(obj);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

事实证明,这个程序编译并有效地改变ptr[0]obj.我发现如果我以+=这种方式声明运算符:

Foo& operator += ( const Foo& obj)
Run Code Online (Sandbox Code Playgroud)

它不编译.为什么是这样?这一发现在我身上产生了许多问题.有没有办法防止函数中指针内容的改变?函数返回常量引用(const Foo&)的含义是什么?声明函数时应该有什么用处const?简而言之,我应该如何const在声明函数中使用?

jua*_*nza 5

const从签名中删除会导致编译错误,因为您无法从const实例调用非const成员函数.

的原因const版本编译并似乎做一些反直觉的是,你正在修改一个对象指向了Mat(假设你的意思/=),或Foo对象,但你没有修改数据成员本身,即指针.

设计表现出这种行为的类型是否有意义是另一回事.就个人而言,我要说的是一个允许的修改 const cv::Mat通过operator /=违反了最小惊讶原则.cv::Mat似乎实现了引用语义(它本质上是一个标题和一个指向数据块的指针),但它可以实现为提供合理的const正确性.它不会通过我参与的任何代码审查.