取消引用常量的指针

Ashim 05/22/2018. 10 answers, 1.312 views
c++

假设我们有一个名为object的类。

int main(){
    object a;
    const object* b = &a;
    (*b); 
} 

问题:b是一个指向const的指针,但它指向的对象实际上不是一个常量对象。 我的问题是,当我们将指针“b”解引用时,为什么我们得到一个常量对象,而不是实际指向的常量对象。

10 Answers


AnT 05/22/2018.

因为这就是内置解除引用操作符*在C ++中的工作原理。 如果取消引用T *类型的指针,则会得到类型T的左值。 在你的情况下, Tconst object

*操作符,而不是指针本身关心(或知道)指针指向的对象实际上是非常量的。 在C ++语言使用的static typing的概念中,它不能是任何其他方式。

在第一层(更深层次)的间接性中,常量限定的全部目的是为您提供创建对象的限制access paths的能力。 也就是说,通过创建一个指向const的指针,即使指针不是恒定的,也是故意并且乐意阻止自己(或其他人)修改指针。


Barmar 05/22/2018.

表达式的类型只是基于表达式中变量的声明类型,它不能依赖动态运行时数据。 例如,你可以写:

object a1;
const object a2;
const object *b;
if (rand() % 2 == 0) {
    b = &a1;
} else {
    b = &a2;
}
(*b); 

*b的类型是在编译时确定的,它不能取决于运行程序时rand()返回的值。

由于b被声明为指向const object ,这就是*b的类型。


CiaPan 05/22/2018.

因为const关键字的意思是'你不能修改那个对象'而不是'该对象不能被修改'。

当您将某个对象传递给某个函数以仅使用该对象的值时,这非常有用,但不会对其进行修改:

// We expect PrintMyString to read the string
// and use its contents but not to modify it

void PrintMyString(const char *string);

void myfunction(int number)
{
    if(param>0 && param<=16]
    {
        char string[17];
        for(i=0, i 

函数PrintMyString将获得一个字符数组,但该数组将作为“只读”传递给该函数。 在拥有函数中该数组肯定是可修改的,但PrintMyString只能读取它获取的内容,而不会更改内容。


codekaizer 05/22/2018.
const object* b = &a; 

这意味着: b is a pointer to a const object

这是一个low-level const ,其中指针指向的对象是const - 使对象指向b不可修改(即只读)。

但是指针可以指向另一个对象,因为它是non-const


low-level const相反,

top-level const是指针本身是const

object *const b = &a;   // b is a const pointer to an object

b = &some_other_object; // error - can't assign b to another object
                        // since b is a const pointer

*b = some_value;        // this is fine since object is non-const 

bipll 05/22/2018.

简单的说,

  1. 对于普通的poiters,一元运算符*的结果是reference to pointed-to typereference to pointed-to type

  2. 因此,如果指向的类型是const限定的,则结果是reference to a constantreference to a constant

  3. 对常量的引用可以绑定到任何对象,甚至可以绑定到相同类型的可变对象。 当你将一个constref绑定到一个值时,你承诺不要通过这个refence临时修改该值(尽管你仍然可以明确地将其转换为非const引用)。

  4. 同样,常量指针可以指向其他方式仍然可以修改的对象。


Paul Sanders 05/22/2018.

这里有很多其他的答案,但我被迫发布这个,因为我觉得其中许多提供了太多的细节,徘徊在主题之外,或者假设OP几乎可以肯定没有C ++术语的知识。 我认为这对OP和其他人在他们职业生涯的相似阶段没有任何帮助,所以我会试着去尝试一些。

情况本身其实非常简单。 声明:

const SomeClassOrType *p = ... 

简单地说,无论p指向哪个指针都不能通过该指针进行修改,并且这对确保通过p访问该对象的代码在不应该修改它时不会修改该代码非常有用。 它最常用于参数声明中,以便函数和方法知道它们是否可以修改传入的对象(*)。

它完全没有提到实际上指向的东西的一致性。 指针本身只是一个简单的灵魂,并不会随身携带这些信息。 它只知道, so far as the pointer is concernedso far as the pointer is concerned的对象可以被读取但不被写入。

具体例子(从CiaPan偷来):

void PrintString (const char *string);

char string [] = "abcde";
const char *p = string;
PrintString (p);

void PrintString (const char *ptr_to_string)
{
    ptr_to_string [0] = 0;   // oops!  but the compiler will catch this, even though the original string itself is writeable
} 

当然,您可以直接将string传递给PrintString ,因为该参数也被声明为const。

另一种看待这种情况的方法是const是程序员提供的信息,以帮助编译器在编译时检查代码的正确性/一致性。 它可以让编译器捕获上面的错误,并可能执行更好的优化。 当你真正运行你的代码时,它就是历史。


(*)现代习惯用法可能是使用const引用,但我不想通过将它扔到主要讨论中来浑浊水域。


gchen 05/22/2018.
const object* b = &a; 

b将把它指向的是const ,即它不能改变

object* const b = &a; 

b本身是const ,即它不能指向其他的object地址,但它可以改变a


Oliver Broad 05/22/2018.

因为在运行时它可能是一个const对象,这意味着在解引用上执行的任何操作都必须与const兼容。 忽略这样一个事实,即在你的例子中它已经指向了一个非const对象,并且不能指向其他任何东西,这种语言不能像那样工作。


Davislor 05/22/2018.

这是一个为什么它是这样的具体例子。 假设你声明:

int a[] = {1, 2, 3};
constexpr size_t n_a = sizeof(a)/sizeof(a[0]);

extern int sum( const int* sequence, size_t n );
sum_a = sum( a, n_a ); 

现在你在另一个模块中实现sum() 。 它不知道你指向的原始对象是如何声明的。 编写一个用这些信息标记指针的编译器是possible ,但是出于许多好的理由,目前没有实际使用的编译器。

sum() ,它可能在一个共享库中,不能用整个程序优化重新编译,你看到的只是一个指向内存的指针,不能被修改。 实际上,在某些实现中,试图通过指向const的指针写入可能会导致程序崩溃并出现内存保护错误。 重新解释内存块作为其他类型的能力对C / C ++很重要。 例如, memset()memcpy()将其重新解释为任意字节的数组。 所以sum()的实现无法告诉它的指针参数的来源。 就它而言,它只是一个指向const int[]的指针。

更重要的是,函数的契约说它不会通过该指针修改对象。它could简单地抛弃const限定符,但这会是一个逻辑错误。 如果你声明一个指针为const ,就像在你的枪上使用安全性一样:你want编译器阻止你在脚中射击。

¹包括从指针中提取地址的额外指令,存储它们的额外内存,与架构的标准调用约定的兼容性,打破许多现有代码,假设事物能够容纳指针,以及缺少任何好处。

²有mutable数据成员的迂腐例外。


CharonX 05/22/2018.

通过写作

const object* b = &a; 

你声明b是一个指针( * )到一个const类型的object ,然后你为其分配一个地址。 aobject类型(但不是const); 您可以使用非const object的地址来代替const object的地址。

然而,当你解除引用* b时,编译器只能根据你的声明进行操作 - 因此*b是一个const object (但是你仍然可以随意修改a ,所以要小心)


HighResolutionMusic.com - Download Hi-Res Songs

1 (G)I-DLE

POP/STARS flac

(G)I-DLE. 2018. Writer: Riot Music Team;Harloe.
2 Ariana Grande

​Thank U, Next flac

Ariana Grande. 2018. Writer: Crazy Mike;Scootie;Victoria Monét;Tayla Parx;TBHits;Ariana Grande.
3 Clean Bandit

Baby flac

Clean Bandit. 2018. Writer: Jack Patterson;Kamille;Jason Evigan;Matthew Knott;Marina;Luis Fonsi.
4 Imagine Dragons

Bad Liar flac

Imagine Dragons. 2018. Writer: Jorgen Odegard;Daniel Platzman;Ben McKee;Wayne Sermon;Aja Volkman;Dan Reynolds.
5 Halsey

Without Me flac

Halsey. 2018. Writer: Halsey;Delacey;Louis Bell;Amy Allen;Justin Timberlake;Timbaland;Scott Storch.
6 BTS

Waste It On Me flac

BTS. 2018. Writer: Steve Aoki;Jeff Halavacs;Ryan Ogren;Michael Gazzo;Nate Cyphert;Sean Foreman;RM.
7 Nicki Minaj

No Candle No Light flac

Nicki Minaj. 2018. Writer: Denisia “Blu June” Andrews;Kathryn Ostenberg;Brittany "Chi" Coney;Brian Lee;TJ Routon;Tushar Apte;ZAYN;Nicki Minaj.
8 Backstreet Boys

Chances flac

Backstreet Boys. 2018.
9 BlackPink

Kiss And Make Up flac

BlackPink. 2018. Writer: Soke;Kny Factory;Billboard;Chelcee Grimes;Teddy Park;Marc Vincent;Dua Lipa.
10 Little Mix

The Cure flac

Little Mix. 2018. Writer: Pete Kelleher;Camille Purcell;Tom Barnes;Ben Kohn.
11 Fitz And The Tantrums

HandClap flac

Fitz And The Tantrums. 2017. Writer: Fitz And The Tantrums;Eric Frederic;Sam Hollander.
12 Diplo

Close To Me flac

Diplo. 2018. Writer: Ellie Goulding;Savan Kotecha;Peter Svensson;Ilya;Swae Lee;Diplo.
13 The Chainsmokers

Beach House flac

The Chainsmokers. 2018. Writer: Andrew Taggart.
14 Bradley Cooper

Always Remember Us This Way flac

Bradley Cooper. 2018. Writer: Lady Gaga;Dave Cobb.
15 Kelly Clarkson

Never Enough flac

Kelly Clarkson. 2018. Writer: Benj Pasek;Justin Paul.
16 Lady Gaga

I'll Never Love Again flac

Lady Gaga. 2018. Writer: Benjamin Rice;Lady Gaga.
17 Frida Sundemo

Apologize flac

Frida Sundemo. 2018.
18 Little Mix

Woman Like Me flac

Little Mix. 2018. Writer: Nicki Minaj;Steve Mac;Ed Sheeran;Jess Glynne.
19 Imagine Dragons

Machine flac

Imagine Dragons. 2018. Writer: Wayne Sermon;Daniel Platzman;Dan Reynolds;Ben McKee;Alex Da Kid.
20 Billie Eilish

When The Party's Over flac

Billie Eilish. 2018. Writer: Billie Eilish;FINNEAS.

Related questions

Hot questions

Language

Popular Tags