C++ 常量引用传递的类的引用成员行为的设计原因
假设你有密码C++ 常量引用传递的类的引用成员行为的设计原因,c++,reference,c++11,C++,Reference,C++11,假设你有密码 #include <iostream> struct A{ int y; int& x; A():y(0),x(y){} }; void f(int& x){ x++; } void g(const A& a){ f(a.x); //f(a.y); } int main(){ A a; g(a); std::cout<<a.y<<std::endl; } 及 是允许的。
#include <iostream>
struct A{
int y;
int& x;
A():y(0),x(y){}
};
void f(int& x){
x++;
}
void g(const A& a){
f(a.x);
//f(a.y);
}
int main(){
A a;
g(a);
std::cout<<a.y<<std::endl;
}
及
是允许的。这非常清楚:我们有一个指向非常量int的常量指针。
但是在前面的引用示例中,如果引用是对象,为什么在这种情况下它们会作为指针?在这种行为下的设计策略是什么?在C++引用中,通常是用指针来实现的。(我认为引用和指针的大小是相同的) 实际上,我通常认为引用是指针,但语法不同 如果引用是对象 不过,引用不是对象-它们是对对象的引用 你是对的,使引用本身保持常量并不是很有用:因为它们是不可重置的,所以在任何情况下都不能像指针一样进行变异 事实上,将引用视为具有特殊语法的常量指针(而不是指向常量的指针!)可能更有帮助 请注意,如果您想要一个间接指令,它将常量从裁判传递到引用对象(即,为了防止
f(a.x)
调用此处),您可以编写一个智能指针样式的东西来执行此操作
具体例子
struct A
{
int x;
int *p;
int &r;
A() : x(0), p(&x), r(x) {}
};
现在在A中:
a.x
是一个可变整数
a.p
是一个可变指针(因此我们可以重置它),指向一个可变int(我们可以更改它指向的整数的值)
- 而
a.r
是对可变整数的引用
- 请注意,由于我们无论如何都不能改变(重置)引用,因此引用本身不是常量,也不是可变的
。。。但是在常数A b中
:
b.x
是一个常量整数
b.p
是指向可变int的常量指针(因此我们无法重置它)
b.r
是对可变整数的引用
- 注意constness是如何应用于A(指针或引用)的成员的,而不是传播到referent的
标准中的实际语言为
8.3.2参考文献[dcl.ref]
1-[…]
[注:可将引用视为对象的名称。-结束注]
因此,如果引用是对象的名称,而不是对象本身,那么使封闭结构为
const
会使名称const
(这是毫无意义的,因为引用不能反弹),而不是对象本身是有意义的
我们也看到
6-
如果类型定义、类型模板参数或decltype规范表示类型TR
这是对类型T的引用,尝试创建类型“对cv TR的左值引用”将创建类型“对T的左值引用”[…]
由于对cv对象的成员访问会创建cv左值,因此同样适用,并且cv限定将被取消。是相同的问题;不过,这可能还不够深入。@ecatmur:谢谢,这完全一样,我会把它链接起来,但是,正如你所说的,这个回答并没有比“因为它像指针一样”更进一步。引用不是对象,它们是对对象的引用。@ereOn我同意,但请参见@FabioDallaLibera:我读过它。请注意,已接受答案中的“是”被强调,表明在解释这句话时需要小心。在某些特定情况下,将引用视为对象有时是可以接受的,因为它简化了逻辑。然而,重要的是要记住,引用在大多数情况下仍然是一种不同的野兽。“我认为引用和指针的大小是相同的”不,我也这么认为,尽管许多人强烈反对它,例如@Cheerrandhth.-Alf你是说它们从来都不一样还是只是有时候?@quamranasizeof(T&)
与sizeof(T)
相同。它与指针的大小无关。用于引用的内存大小可以是0或与T*
相同,或者由编译器自行决定,并且不能通过sizeof
获得(要检查它,您可以将引用放在结构中)。谢谢。我认为@UffuseComment在这里增加了一件重要的事情:引用本身const不是很有用:因为它们是不可重置的,所以在任何情况下都不能像指针一样进行变异。谢谢!这里是第6点:typedef int&C;模板结构V{const X&X;V(X&px):X(px){};intmain(){intx;ccc(x);vv(C);V.x=3;}谢谢。我喜欢你的回答。现在是下一步。结构B{int*x;}现在,常数B与具有int*const的B相同;但是,对于结构C{int&x;},x不是常量int&。你怎么称呼它?不,aconst B
有一个const成员x,也就是说int*const B::x
。该成员是一个指针,因此const成员是一个const指针,而不是指向const的指针。因此,您仍然可以修改x
指向的任何内容,但您不能修改x
(通过重新放置)。谢谢。我为报告标准的摘录标记了@ecatmur response,但我也可以将您的答案标记为已接受的答案。我要把分数加起来
g(const B&){
*x++;
}
struct A
{
int x;
int *p;
int &r;
A() : x(0), p(&x), r(x) {}
};