struct S {
S() {}
S (const S &) = delete;
};
void f1 (S s) {}
void f2 (S &s) {}
int main() {
S s;
f2(s);
}
既然S(S &s)
被删除了,为什么 usingf2
不抛出错误,因为它被声明时它传递了参数S &s
?当我使用f1(s)
它时会引发错误。我查看了已删除函数的定义,我认为这会引发错误,但事实并非如此。为什么?
struct S {
S() {}
S (const S &) = delete;
};
void f1 (S s) {}
void f2 (S &s) {}
int main() {
S s;
f2(s);
}
既然S(S &s)
被删除了,为什么 usingf2
不抛出错误,因为它被声明时它传递了参数S &s
?当我使用f1(s)
它时会引发错误。我查看了已删除函数的定义,我认为这会引发错误,但事实并非如此。为什么?
因为通过引用传递不会创建副本(这是f2
使用的)。
f1
另一方面,它接受一个按值传递的参数,该参数会生成一个副本。
让我们看看S
:
struct S {
S() {} // default constructor
S (const S &) = delete; // copy-constructor
};
您在这里拥有的是一种可以构造但不能复制的类型。
现在让我们看看你的函数:
void f1 (S s1) {} // creates a local copy of its parameter
void f2 (S &s2) {} // takes a reference to the parameter
当您调用 时f1(s)
,该函数会尝试创建一个副本s
- 但您的类型S
禁止复制 - 这就是它不起作用的原因。
当您调用时f2(s)
,该函数会创建对其参数的引用——因此您在内部执行的任何f2
操作s2
都会直接针对原始对象执行s
。类无法阻止任何人获取对象的引用。