例如,如果F是对整数的引用,则一旦初始指向一个对象,就不允许将引用指向新对象。
我可以写声明如下:const int& F'
我对引用和指针感到困惑,因为它们都代表了某些东西的地址,但是我们总是把参数使用引用写成:const& F,我明白这是为了减少副本而不允许其他人改变副本,但还有其他含义吗?为什么在函数声明之后需要“const”,如:int F(int z)const;这个const使得返回类型为const或函数const中的所有内容?
还有一个例子,
void F(int* p)
{
p+=3;
}
int z=8;
F(&z);
std::cout<<z<<std::endl;
z的输出是什么,因为z是一个引用,我把它作为一个指向一个整数的指针传递。将p增加3只会使地址不同而不会改变它的值?
答案 0 :(得分:2)
只是第一次传递一些答案 - 如果有什么不清楚请发表评论,我会尽力详细说明。
int a = 3;
声明一个整数a
,初始值为3,但您可以更改它。例如,稍后你可以做
a = 5; // (*)
和a
的值为5.如果要阻止这种情况,可以改写
const int a = 3;
将使赋值(*)
非法 - 编译器将发出错误。
如果创建对整数的引用,则基本上是在创建别名:
int& b = a;
,尽管出现,但不会创建新的整数b
。相反,它将b
声明为a
的别名。如果a
之前的值为3,那么b
也是如此,如果您编写b = 6
并打印a
的值,您也会获得6。与a
一样,您可以通过将赋值b = 6
声明为const来使其成为非法的:
const int& b = a;
表示b
仍然是a
的别名,但不会用于为a
分配不同的值。它仅用于读取a
的值。请注意,a
本身仍然可能是或可能不是常量 - 如果您将其声明为非const
,您仍然可以写a = 6
而b
也会6
}。
关于指针的问题:片段
void F(int* p) {
p += 3;
}
int z = 8;
F(&z);
不符合您的预期。您将z
的地址传递给函数F
,因此在F
内,指针p
将指向z
。但是,您正在执行的操作是将3
添加到p
的值,即p
指向的地址。因此,您将更改为指向某个(半)随机存储器地址的指针。幸运的是,它只是一个副本,它将被丢弃。您可能希望做的事情是将p
指向的整数值增加到,这将是*p += 3
。您可以通过将参数设为int* const
来防止此错误,这意味着:p
(即指向的地址)的值不能更改,但它指向的值(即{{{1}的值1}},在这种情况下)可以。这会使z
合法,但不会是“错误的”(非预期的)*p += 3
。其他版本将是p += 3
,这将使const int* p
合法但不是p += 3
,而const int * const`则不允许。
实际上,您编写*p += 3
的方式是危险:假设您展开该函数,然后您(正确地)F
编写。您认为您正在更新传入其地址的*p += 3
的值,而实际上您正在更新或多或少的随机存储器的值地址。事实上,当我尝试编译以下内容时:
z
我遇到了分段错误,因为我正在写一个我没有分配变量的地址(据我所知,我可能只是搞砸了我的启动扇区)。
最后,关于函数声明后的// WARNING WARNING WARNING
// DANGEROUS CODE - This will probably produce a segfault - don't run it!
void F(int* p) {
p += 3; // I thought I wrote *p += 3
// ... Lots of other code in between, I forgot I accidentally changed p
*p += 3; // NOOOOOOOOOOO!
}
int main()
{
int z=8;
F(&z);
std::cout << z;
return 0;
}
:它使const
指针成为this
指针 - 基本上编译器发出const
代替仅const A* this
。从概念上讲,它表明你的意图是函数不会改变类的状态,这通常意味着它不会改变任何(内部)变量。例如,它会使以下代码非法:
A* this
当然,如果函数返回某些内容,则此值可以有自己的类型,例如
class A {
int a;
void f() const {
a = 3; // f is const, so it cannot change a!
}
};
A a;
a.f();
是不返回任何内容的函数,整数的(副本),整数的(引用),整数的常量(副本)以及整数的常量引用。如果另外void f();
int f();
int& f();
const int f();
const int& f();
保证不更改任何类字段,您还可以在括号后添加f
:
const
答案 1 :(得分:1)
我记得引用和指针之间的区别在于必须存在引用并且引用不能更改。
指针可以更改,通常需要针对NULL进行检查或测试以验证指向有效对象。
此外,通过引用传递的对象可以在语法上处理,就像在函数中声明的那样。指针必须使用引用语法。
希望有所帮助。
答案 2 :(得分:1)
你很困惑。
首先int z=8; F(&z);
这里z不是参考。
让我先从基础知识开始:
当在类型声明中找到时,符号&
表示引用,但在任何其他上下文中,符号&
表示地址。
类似地,在类型声明中*
具有声明指针的含义,在其它任何地方它都是解引用运算符,表示你使用地址处的值。
例如:
int *p
:p是int类型的指针。
x = *p
:x被指定为在地址 p。
int &r = a
:r是int类型的引用,r是变量a。
p = &a
:p被指定为变量的地址 a。
你有另一个问题:函数末尾的const,如int f(int x) const
。这可以在非静态类方法上使用 only ,并指定该函数不会修改该对象。它与返回值无关。