C++中引用的const语义学问题

4
如果代码中有以下内容:
func(const base& obj)

const语义是什么意思?这里的常量是什么?obj是一个非const对象的const引用还是一个const对象的非const引用

8个回答

6

不存在所谓的“非const引用”,也就是说,引用总是绑定到同一个对象上,没有办法改变它。 “const type&”表示对const类型的引用。


所以 const base &obj 也可以被写成 base const &obj 吗? - nitin_cherian
那是错误的。根据标准,非const引用是存在的。 - Hicham
“const type&” 表示对常量类型的引用。根据标准,这是对无论是常量还是非常量对象的 const 引用。 - Hicham
@LinuxPenseur: "const base&"和"base const&"是相同的类型。 - Tavian Barnes
1
@eharvest:存在对非const对象的引用。在C++中,不存在可以自身可变(即可以更改所引用对象)的引用。 - Tavian Barnes

5

obj 是指向常量对象的引用。

“非常量引用”是不存在的,因为一旦创建引用之后,它就不能被改变,也就不能指向其他东西。


那么只有一个常量对象可以作为“func”的参数传递吗? - nitin_cherian
3
任何对象(无论是否为const)都可以作为参数传递。但是,在函数func()内,对该对象的使用仅限于那些在const对象上有效的操作。因此,调用者知道调用func(obj)不会改变obj - Greg Hewgill
1
谢谢。对于像我这样的初学者来说,那真是太有用了 :) - nitin_cherian
有一个常量引用:无法修改所引用的对象。还有一个引用指向可以更改所引用对象内容的对象。因此,存在... - Hicham
这对指针是正确的,但对于引用则不然。引用的行为和使用与指针不同。 - Hicham
显示剩余3条评论

2
它被称为常量引用。您可以对传递的数据进行"引用访问",但是无法修改它。

2

如果没有const,您将无法将一个const对象发送到该函数。因此,始终添加const是一个积极的选择,尤其是当您为许多用户创建函数时。经典的例子是设置器函数。

x->setXsth(sth& obj)              // works only with  non-const object. 
x->setXsth(const sth& obj)        //works with  const object and non-const.

1

obj是对const base的引用,这意味着您不允许更改所引用的对象。它可以写成

func(const base& obj)

或者

func(base const & obj)

在阅读这些声明类型时,请使用从右到左的规则,对于这个简单的例子,只需从右边开始阅读。更多信息请参见此处:

http://www.codeproject.com/KB/cpp/complex_declarations.aspx


尽管'base const&obj'可能一开始看起来很奇怪,但它更容易阅读,您只需按照右侧的写法即可:obj是对const base的引用。 - marcinj

0

obj 是一个常量引用,指向作为参数传递给 func() 的对象(无论该对象是 const 还是非 const)

如果你写: func(B);

这意味着你不能在函数 func() 内更改 B 的内容

(其中 func(const base& obj))


1
我没有点踩,但是谁点了可能反对“常量引用对象”。大多数人会说“引用常量对象”。 - Oliver Charlesworth
但是并不存在所谓的“非const引用”,因此只需要说“引用”即可。 - Greg Hewgill
1
@eharvest:我们称这些为“T的引用”和“const T的引用”。 - Oliver Charlesworth
在标准中是错误的:你不能调用对“const T”的引用!!!(即我向你解释,T可以是const或非const,但引用不能更改T内容)。 - Hicham
常量引用写在标准上。 - Hicham
显示剩余7条评论

0
有点不请自来的回答/观点: const 修饰符修改其左侧的任何内容,除了您正在使用的一种构造(在这种情况下,它会修改紧接在右侧的任何内容)。我发现将 const 立即放在要修改的任何内容的右侧并从右到左阅读语句更容易理解。也许这不是最好的做法,但它有助于我保持清晰明了。

例如:

// these two statements are equivalent
const int x = 5; // special case usage
int const x = 5;

// using the LHS syntax makes multiple consts easier to understand
int const y = 6;
int const * const x = &y; // x is a const pointer to const int

// const can apply to pointers but not to references
int const & const z = y; // redundant, references are always const

-1

正如其他答案所说,obj 是一个指向 const base 对象的引用。然而,这并不意味着它所引用的对象具有完全相同的 base 类型,或者它所引用的对象是 const 的,只是 func 不能通过 那个 引用修改 obj。例如:

struct derived : base { ... };
derived d;
func(d);

是合法的,并且:

bool other_func(const base& b, other_object& o) {
   base b_copy = b;
   o.foo();
   return b_copy == b;
}

如果o具有对b(或其内部某些内容)的内部非const引用,并且o.foo()修改了b,则可能返回false。这对于像此类函数的实际应用具有实际意义:

std::string::operator=(const std::string& other);

在一个天真的实现中,可能会出现my_str = my_str错误的情况。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接