由于我们在C++中移动了语义,所以现在通常这样做
void set_a(A a) { _a = std::move(a); }
Run Code Online (Sandbox Code Playgroud)
原因是,如果a是左值,则副本将被删除,并且只有一个移动.
但如果a是左值,会发生什么?似乎将有一个复制结构,然后是一个移动赋值(假设A有一个适当的移动赋值运算符).如果对象具有太多成员变量,则移动分配可能成本很高.
另一方面,如果我们这样做
void set_a(const A& a) { _a = a; }
Run Code Online (Sandbox Code Playgroud)
只有一个副本分配.如果我们传递左值,我们可以说这种方式优于传值的习语吗?
最近我偶然发现了 Rust 和 C 之间的比较,它们使用以下代码:
bool f(int* a, const int* b) {
*a = 2;
int ret = *b;
*a = 3;
return ret != 0;
}
Run Code Online (Sandbox Code Playgroud)
在 Rust(相同的代码,但使用 Rust 语法)中,它生成以下汇编代码:
cmp dword ptr [rsi], 0
mov dword ptr [rdi], 3
setne al
ret
Run Code Online (Sandbox Code Playgroud)
使用 gcc 时,它会产生以下结果:
mov DWORD PTR [rdi], 2
mov eax, DWORD PTR [rsi]
mov DWORD PTR [rdi], 3
test eax, eax
setne al
ret
Run Code Online (Sandbox Code Playgroud)
文本声称 C 函数不能优化第一行,因为a和b可能指向相同的数字。在 Rust 中这是不允许的,因此编译器可以将其优化掉。
现在我的问题:
该函数采用一个const …
考虑一下:
#include <functional>
#include <iostream>
std::function<void()> make_function(int& x) {
return [&]{ std::cout << x << std::endl; };
}
int main() {
int i = 3;
auto f = make_function(i);
i = 5;
f();
}
Run Code Online (Sandbox Code Playgroud)
是否保证在5不调用未定义行为的情况下输出该程序?
我理解如果我x通过value([=])捕获它是如何工作的,但我不确定我是否通过引用捕获它来调用未定义的行为.可能是我在make_function返回后最终会有一个悬空引用,或者只要原始引用的对象仍然存在,捕获的引用是否可以保证工作?
在这里寻找明确的基于标准的答案:) 到目前为止它在实践中运作良好;)
我在函数声明中多次发现这些符号,但我不知道它们是什么意思.
例:
void raccogli_dati(double **& V, double **p, int N) {
int ultimo = 3;
V = new double * [N/2];
for(int i=0; i < N/2; i++) {
V[i] = new double[N/2], std :: clog << "digita " << N/2 - i
<< " valori per la parte superiore della matrice V: ";
for(int j=i; j < N/2; j++)
std :: cin >> V[i][j], p[ultimo++][0] = (V[i][j] /= sqrt(p[i][0]*p[j][0]));
}
for(int i=1; i < N/2; i++)
for(int j=0; j < …Run Code Online (Sandbox Code Playgroud) 可能重复:
C++中指针变量和引用变量之间有什么区别?
这令我困惑:
class CDummy
{
public:
int isitme (CDummy& param);
};
int CDummy::isitme (CDummy& param)
{
if (¶m == this)
{
return true; //ampersand sign on left side??
}
else
{
return false;
}
}
int main ()
{
CDummy a;
CDummy* b = &a;
if ( b->isitme(a) )
{
cout << "yes, &a is b";
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在C&中通常表示var的地址.这是什么意思?这是指针符号的奇特方式吗?
我假设它的原因是一个指针表示法,因为这毕竟是一个指针,我们正在检查两个指针的相等性.
我正在从cplusplus.com学习,他们有这个例子.
在这两种情况下,我都取得了成果.那么什么时候优先于另一个呢?我们使用其中一个的原因是什么?
#include <iostream>
using namespace std;
void swap(int* x, int* y)
{
int z = *x;
*x=*y;
*y=z;
}
void swap(int& x, int& y)
{
int z = x;
x=y;
y=z;
}
int main()
{
int a = 45;
int b = 35;
cout<<"Before Swap\n";
cout<<"a="<<a<<" b="<<b<<"\n";
swap(&a,&b);
cout<<"After Swap with pass by pointer\n";
cout<<"a="<<a<<" b="<<b<<"\n";
swap(a,b);
cout<<"After Swap with pass by reference\n";
cout<<"a="<<a<<" b="<<b<<"\n";
}
Run Code Online (Sandbox Code Playgroud)
产量
Before Swap
a=45 b=35
After Swap with pass by pointer …Run Code Online (Sandbox Code Playgroud) 我是一个C人,我正在尝试理解一些C++代码.我有以下函数声明:
int foo(const string &myname) {
cout << "called foo for: " << myname << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
函数签名与等效的C有何不同:
int foo(const char *myname)
Run Code Online (Sandbox Code Playgroud)
使用string *mynamevs 之间有区别string &myname吗?&用C++和*C表示指针有什么区别?
同理:
const string &GetMethodName() { ... }
Run Code Online (Sandbox Code Playgroud)
这是&做什么的?是否有一些网站解释了如何&在C vs C++中使用不同的方式?
常量指针和引用之间有什么区别?
顾名思义的常量指针不能再绑定.参考的情况也是如此.
我想知道在哪种情况下优先于另一种情况.他们的C++标准及其实现有何不同?
干杯
我正在使用ref并且不明白"它是像C/C++中的指针还是像C++中的引用一样?"
为什么我问你这么弱的问题?因为,当我正在阅读C#/.NET书籍,msdn或与C#开发人员交谈时,我会因以下原因而感到困惑:
ref在函数的参数中使用,e.g. ...(ref Type someObject)对他们没有好处,他们建议...(Type someObject),我真的不明白这个建议.我听到的原因:更好地处理对象的副本,然后将其用作返回值,而不是通过引用等来破坏内存...通常我会听到有关数据库连接对象的这种解释.就像我简单的C/C++体验一样,我真的不明白为什么使用引用是C#中的坏东西?我控制对象的生命及其内存分配/重新分配等...我在书籍和论坛中只读了建议it's bad, because you can corrupt your connection and cause a memory leak by a reference lose,所以我控制对象的生命,我可以手动控制我真正想要的东西,那为什么它不好?ref一个指针(*)或像C++中的引用&吗?我记得C/C++中的指针总是分配一个大小为void*4字节的空间(有效大小取决于体系结构),其中主机是结构或变量的地址.在C++中,通过传递引用&,没有来自堆/堆栈的新分配,并且您在内存空间中使用已定义的对象,并且外部没有像在纯C中那样的指针的子分配内存.那么refC#中的内容是什么?.NET VM是否像普通C/C++中的指针一样处理它,它为指针GC分配临时空间,还是像C++中的引用那样工作?是否ref只能正确使用托管类型或者类似于值类型bool, int,更好地切换unsafe代码并以非托管样式传递指针?