这里需要使用const吗?

时间:2018-07-21 16:54:20

标签: c++

在参考参数方面,我开始对const有所了解。我所看到的是,常量引用参数基本上将有问题的参数设置为将函数有问题的原始内存空间。而且由于它是const,因此其值本身无法更改。

对于提供矩阵乘法A=BC的代码,我发现了一个解决方案:

vector<vector<double> > mult(const vector<vector<double> >& B, const vector<vector<double> >& C)
{ ...;
return A;
}

int main()
{
vector<vector<double> > B, C;
cout << mult(B,C) << endl;
return 0;
}

我同意代码的结构,但对“ const”和“&”的必要性感到困惑。如果我从上述两个方面都排除了,代码肯定会完全相同吗?对于“&”,也许可以通过不为“ mult”参数创建额外的空间来使用更少的内存空间。但是对我来说,使用const似乎是不必要的。

4 个答案:

答案 0 :(得分:1)

'&'防止调用副本构造函数,即,防止创建重复副本。这样比较有效,因为您避免了调用时的构造函数和出口时的析构函数。

'const'关键字通知调用者该引用所引用的对象在该函数中不会更改。它还允许使用常量向量作为输入来调用该函数。换句话说,如果B和C是常数,则签名中没有const关键字就无法调用mult()。

对我来说,使用C ++已经有一段时间了,但是我认为这是要旨。我当然愿意对自己的答案进行更正。

答案 1 :(得分:1)

严格来说,const引用是必要的几次。最常见的是需要通过引用传递const对象的情况。类型系统将阻止这种情况,除非该函数承诺不修改该对象。当对象是const且您特别想要const版本时,如果函数重载以执行某些操作,这也会有所不同。 (后者可能是错误的设计!)

或者可以从函数参数中删除const限定符,并为所有重载函数提供不同的名称。实际上,C ++中的引用是C风格指针的语法糖,可以将void foo (T& x)替换为void foo(T* x),并将xfoo的每次出现都替换为{ {1}}。添加(*x)const T&只是意味着程序将无法通过该引用或指针来修改对象。

C直到1989年才没有T* const关键字,没有它,您可以做所有相同的事情,但是它的存在是为了帮助开发人员避免与修改错误的变量有关的错误。

答案 2 :(得分:0)

int sum(const int a,int b)
{
  b=10;
  // a=5; error
  return (a+b);
}
在上面的示例中,

a是const而不是b。 因此a为只读变量。如果尝试更改a的值,则会出错。这意味着您必须使用值a,该值在调用函数时通过。

答案 3 :(得分:0)

这不是真正必要的。只要将非const参数传递给函数,程序的行为就不会改变。

在您的情况下,我可以举几个例子:
如果您必须传递的参数之一是const,它将不起作用。
此外,您将无法执行类似mult({{1, 2}, {3, 4}}, b);的操作,因为该临时对象只能隐式转换为const引用。
如果将定义和声明放在单独的翻译单元(即.cpp文件中),则编译器可能会错过一些优化潜力,因为它无法假定mult()没有修改其参数。
另一个说法是const可以更清楚地显示您的意图。
isocpp上查看更多原因。

引用&可防止不必要的复制。您的参数类型为std::vector,这意味着复制将涉及内存分配,出于性能原因,您不希望这样做。

另一方面,如果您的代码用于处理矩阵,则出于性能方面的考虑,std::vector中的std::vector是非常不适当的,因为它使缓存效率极低并且会导致不必要的动态分配。您宁愿使用1D std::array并将其包装起来以很好地处理2D​​索引。 std::array的大小称为编译时间,这意味着您传递一个特定的std::array的每个函数都知道其在编译时的大小,这对性能很有好处,尤其是std::array避免动态分配。