康斯坦德是做什么的?
What does const& do?
我不明白这是怎么回事。我刚刚学习c++,我经常看到这样的东西:
double some_function(const Struct_Name& s) {
...
}
如果我们通过引用传递,为什么是const
?
当您不想(或不能)修改传入的参数,并且您不希望复制对象可能会导致性能下降时,您可以通过const引用传递。
const
引用防止对象被修改,就像const
在其他地方一样,但也避免了复制的潜在成本。
你在告诉编译器你永远不会改变s。
这使它能够进行一些优化,否则它将无法做到。基本上,它提供了与按值传递相同的语义,但不会导致调用复制构造函数的性能损失。
通过const-reference调用避免了Struct_Name
的复制,同时保证不修改它。
这既有性能上的原因,也有语义上的原因。
如果Struct_Name
很大,复制它在时间和内存上都很昂贵。
如果Struct_Name
是不可复制的(或在复制时无效),则不可能按值调用或引入不必要的复杂性。例如:std::unique_ptr
、std::auto_ptr
通过使用const
,我们可以通知函数的用户和编译器,作为参数s
传递的对象在函数内部不会被更改(这实际上是可能的,因为我们通过引用传递它!)如果我们不小心修改了对象,编译器可能会给我们一个错误,它可以做一些其他情况下无法做的优化。
一个额外的优点是,如果函数的调用者只拥有指向对象的const
指针,它仍然可以将该对象作为参数提供,而不需要强制转换。
const这里承诺some_function不会修改参数,
double some_function(const Struct_Name& s) {
...
}
你可以尝试修改它,但是编译器会返回错误。实际上,constness要求你仔细编写Struct_Name内部方法。你将不能在some_function内部调用对象上的非const函数。你可以试试,但你会得到错误。即:
struct Struct_Name {
void myfun() const { } // can be called from some_function
void myfun2() { } // will show error if called from some_function
};
从设计的角度来看,使用const参数是好的,如果你知道某些函数不应该改变你的对象,那么你就添加const。这意味着没有其他程序员可以对一些隐藏在类层次结构中的代码进行修改,这些代码将修改您的对象。
另一个没有人提到的原因——如果输入值不是参数中声明的确切类型,但该类型有一个支持传入类型的构造函数,则通过const
引用允许编译器创建并传递临时对象,而不会产生警告。
void foo(const std::string &s)
{
...
}
foo("hello"); // OK
foo()
期望std::string
,但收到的却是const char*
。由于std::string
有一个接受const char*
的构造函数,编译器生成的代码可以有效地执行以下操作:
std::string temp("hello");
foo(temp);
编译器知道参数是const
, foo()
不会改变临时,foo()
退出后临时将被丢弃,所以它不会抱怨必须创建一个临时。
如果参数通过值传递(const
或非const
,这无关紧要),而不是通过引用传递,也会发生同样的事情:
void foo(const std::string s)
{
...
}
void bar(std::string s)
{
...
}
foo("hello"); // OK
bar("world"); // OK
这实际上与以下相同:
{
std::string temp1("hello");
foo(temp1);
}
{
std::string temp2("world");
bar(temp2);
}
同样,编译器不会报错,因为它知道临时变量不会影响调用代码,并且bar()
中对临时变量所做的任何更改都将被安全地丢弃。
如果参数是一个非const
引用,传递const char*
将生成一个关于必须创建的临时的警告,以满足引用绑定。这个警告是为了让您知道,函数对临时对象(因为它不是const
)所做的任何更改都会在函数退出时丢失,这可能会对调用代码产生影响,也可能不会。这通常表示在这种情况下不应该使用临时变量:
void foo(std::string &s)
{
...
}
foo("hello"); // warning!
- 在C++上实现高斯赛德尔迭代方法
- C++程序什么都不做,但瓦尔格林德显示内存分配
- 运行莱文斯坦代码时出现问题
- Q 斯坦达项重定义错误
- 康斯坦特还行,但不是康特克斯普尔?
- 什么是斯特伦省略?
- 从字符到康斯特* 字符的转换无效,代码有什么问题?
- 用于双向迭代器的高德纳-莫里斯-普拉特算法
- 为什么在 C++ 中实现高斯勒让德算法没有产生结果
- 如何在我指向的安德烈斯上动态分配内存?
- 使用弗洛伊德-斯坦伯格抖动不起作用
- 康斯坦德是做什么的?
- 高斯-塞德尔法计算3个系统的线性方程
- 在Linux中,首先执行体为空的for循环.斯坦格的行为
- 伯恩斯坦多项式插值
- 在OpenGL中绘制斯坦纳的罗马曲面
- 高斯-赛德尔函数中的无效类型
- 红黑高斯塞德尔和OpenMP
- 有可能用任意后验函数来定义斯坦模型吗
- 求解非线性方程组的高斯-塞德尔方法