为什么这样:
#include <string>
#include <iostream>
using namespace std;
class Sandbox
{
public:
Sandbox(const string& n) : member(n) {}
const string& member;
};
int main()
{
Sandbox sandbox(string("four"));
cout << "The answer is: " << sandbox.member << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
给出输出:
答案是:
代替:
答案是:四
template<typename T>
void f(T a, const T& b)
{
++a; // ok
++b; // also ok!
}
template<typename T>
void g(T n)
{
f<T>(n, n);
}
int main()
{
int n{};
g<int&>(n);
}
Run Code Online (Sandbox Code Playgroud)
请注意:b
是的const T&
,++b
没关系!
为什么const T&
不确定是const?
我正在为一个机器学习库编写一些模板化的类,我很多时候都面临这个问题.我主要使用策略模式,其中类接收作为不同功能的模板参数策略,例如:
template <class Loss, class Optimizer> class LinearClassifier { ... }
Run Code Online (Sandbox Code Playgroud)
问题在于构造函数.随着策略量(模板参数)的增长,const引用和右值引用的组合呈指数级增长.在前面的示例中:
LinearClassifier(const Loss& loss, const Optimizer& optimizer) : _loss(loss), _optimizer(optimizer) {}
LinearClassifier(Loss&& loss, const Optimizer& optimizer) : _loss(std::move(loss)), _optimizer(optimizer) {}
LinearClassifier(const Loss& loss, Optimizer&& optimizer) : _loss(loss), _optimizer(std::move(optimizer)) {}
LinearClassifier(Loss&& loss, Optimizer&& optimizer) : _loss(std::move(loss)), _optimizer(std::move(optimizer)) {}
Run Code Online (Sandbox Code Playgroud)
有没有办法避免这种情况?
你能解释一下返回值,引用值和const引用值之间的区别吗?
值:
Vector2D operator += (const Vector2D& vector)
{
this->x += vector.x;
this->y += vector.y;
return *this;
}
Run Code Online (Sandbox Code Playgroud)
非const引用:
Vector2D& operator += (const Vector2D& vector)
{
this->x += vector.x;
this->y += vector.y;
return *this;
}
Run Code Online (Sandbox Code Playgroud)
Const参考:
const Vector2D& operator += (const Vector2D& vector)
{
this->x += vector.x;
this->y += vector.y;
return *this;
}
Run Code Online (Sandbox Code Playgroud)
这有什么好处?我理解const引用传递给函数背后的意义,因为你要确保不要修改引用指向函数内部的这个值.但我对返回const引用的含义感到困惑.为什么返回引用比返回值更好,为什么返回const引用要比返回非const引用更好?
c++ reference const-reference return-by-reference return-by-value
我有一些关于从函数返回对局部变量的引用的问题:
class A {
public:
A(int xx)
: x(xx)
{
printf("A::A()\n");
}
};
const A& getA1()
{
A a(5);
return a;
}
A& getA2()
{
A a(5);
return a;
}
A getA3()
{
A a(5);
return a;
}
int main()
{
const A& newA1 = getA1(); //1
A& newA2 = getA2(); //2
A& newA3 = getA3(); //3
}
Run Code Online (Sandbox Code Playgroud)
我的问题是=>
执行getA1()
是否正确?我觉得它是错误的,因为它返回局部变量的地址或临时变量.
main
(1,2,3)中的哪些陈述会导致未定义的行为?
在const A& newA1 = getA1();
做标准的保证,暂时由const引用约束不会被破坏,直到引用超出范围是什么?
这是我从来没有用const-ref得到的东西,我真的希望有人可以向我解释.
当调用另一个函数内部的函数时,我得到的const-ref是传递我不打算篡改的堆栈对象的最佳方法.例如:
void someInnerFunction(const QString& text) {
qDebug() << text;
}
void someFunction() {
QString test = "lala";
....
someInnerFunction(test);
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,我觉得这么好.但信号怎么样?传递参考文件是否存在任何风险?即便如此const
.感觉就像我一直在阅读关于const-ref的所有文档,但我仍然觉得有点冒险,因为我将其理解为"发送一个对象的引用并保持它const
".如果它所指的对象超出范围怎么办?
例如:
void someFunction() {
connect(this, SIGNAL(someSignal(const QString&)), this, SLOT(someSlot(const QString&)));
QString test = "lala";
emit someSignal(test);
// doesnt test go out of scope here? and since im not using queued connection the QString object doesnt get copied.
}
void someSlot(const QString& test) {
qDebug() << test; // will this work?
}
Run Code Online (Sandbox Code Playgroud)
这里到底发生了什么?我经常在函数调用中使用const-ref,我只想访问该对象但不更改它.但信号怎么样?大多数信号在Qt doc中似乎都有const-ref parm,但它是如何工作的?
c++ qt signals-slots const-reference pass-by-const-reference
这里有两个相关的问题:
A)如何实现枚举?例如,如果我有代码:
enum myType
{
TYPE_1,
TYPE_2
};
Run Code Online (Sandbox Code Playgroud)
究竟发生了什么?我知道您可以将TYPE_1和TYPE_2视为整数,但它们实际上只是整数?
B)基于该信息,假设传入的枚举不需要更改,将myType作为值或const引用传递给函数会更有意义吗?
例如,哪个是更好的选择:
void myFunction(myType x){ // some stuff }
Run Code Online (Sandbox Code Playgroud)
要么
void myFunction(const myType& x) { // some stuff }
Run Code Online (Sandbox Code Playgroud) 我知道为一个const左值引用分配一个rvalue会延长临时值的生命周期,直到范围结束.但是,我不清楚何时使用它以及何时依赖返回值优化.
LargeObject lofactory( ... ) {
// construct a LargeObject in a way that is OK for RVO/NRVO
}
int main() {
const LargeObject& mylo1 = lofactory( ... ); // using const&
LargeObject mylo2 = lofactory( ... ); // same as above because of RVO/NRVO ?
}
Run Code Online (Sandbox Code Playgroud)
根据Scot Meyers的"更有效的C++"(第20项),编译器可以优化第二种方法来构建适当的对象(这将是理想的,并且正是人们试图用const&
第一种方法实现的).
const&
临时工具以及何时依赖RVO/NRVO?const&
方法比不使用该方法更糟糕的情况?(我正在考虑关于C++ 11移动语义的例子,如果LargeObject
实现了那些......)c++ optimization const-reference temporary-objects return-value-optimization
我在理解此代码段中的行为时遇到了一些麻烦:
unsigned int i = 2;
const int &r = i;
std::cout << r << "\n";
i = 100;
std::cout << r << "\n";
Run Code Online (Sandbox Code Playgroud)
第一个print语句按预期给出2,但是当我更改引用变量的值时,它不会反映在引用中.第二个印刷声明也给出2,但我认为它应该给100?
如果我将变量i
变为类型int
而不是unsigned int
,它就像我期望的那样工作.这里发生了什么?
我真的很佩服java功能,我不想放弃使用它来解决下一个问题:
我有一个可能被继承的类,并且它内部是一个private ArrayList arr;
所以setter函数是可以的,但是getter函数return arr;
返回对该变量的引用,任何人都能够编辑我不想要的整个数组并且私有不会'没有任何意义!
在C++中,我只是return const arr;
会返回对变量的常量引用.
我非常需要变量不被克隆或手动复制,因为有太多的计算需要(只读变量)为什么在java中没有返回const?有什么方法可以逃避复制吗?
ps (final ArrayList<Integer> arr;)
不是一个选项,因为该数组总是更改大小或元素值.
如果我找不到解决方法,我威胁要回到C++或公开所有内容,你永远不应该得到我的软件:D
编辑:一个更重要的问题:我要求的东西不好(软件工程明智)我的意思是如果JAVA创建者认为没有const引用(返回只读引用)那么我必须要求可以在其他地方处理的东西办法.或者我的程序设计错了我很困惑.
const-reference ×10
c++ ×9
reference ×3
const ×2
performance ×2
c++11 ×1
enums ×1
java ×1
optimization ×1
qt ×1
return ×1
templates ×1
temporary ×1
undefined ×1