C ++中关于常量指针的问题?

3

以下代码我无法解释:

   double d = 100;

    double const d1 = 30;

    double* const p = &d; // Line 1
    double* const p1 = &d1; // Line 2

在上述代码中,第一行是正确的,但第二行会产生错误:
"error C2440: 'initializing' : cannot convert from 'const double *__w64 ' to 'double *const '"

请问有人能详细解释一下吗?(我正在使用运行在Win XP SP3上的VS C++ 2005)


3
好的,我会尽力进行翻译。以下是您要翻译的内容:请阅读:http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.5 - Adam Jurczyk
4个回答

11
类型double* const是指向非const double的const指针。如果你想要一个指向const double的指针,你需要使用double const*(或者double const* const如果你想要一个指向const double的const指针)。
在C++中,用一个简单的指向double的指针,可以独立配置指针本身的const性质(即,你能否使它指向另一个位置),以及值的const性质(你能否通过指针改变这个值)。这给出了四种非常相似但不兼容的类型:
double const* const p1; // Const pointer to const double
                        //  . you can't have the pointer point to another address
                        //  . you can't mutate the value through the pointer

double const* p2;       // Non-const pointer to const double
                        //  . you can have the pointer point to another address
                        //  . you can't mutate the value through the pointer

double* const p3;       // Const pointer to double
                        //  . you can't have the pointer point to another address
                        //  . you can mutate the value through the pointer

double* p4;             // Non-const pointer to non-const double
                        //  . you can have the pointer point to another address
                        //  . you can mutate the value through the pointer

@wormsparty:不需要的。double const *p2 =&d1; 是可以的。在 pp1 的定义中使用的 const 可以防止它们后来被更改为包含不同地址,所以如果他需要这样做,并且需要能够指向 const double,例如 d1,那么他需要 double const *const - Steve Jessop
由于d1是一个const int,所以可以这样做:const double* p1 = &d1; - RoundPi

4

double * const p1 声明一个指向非 constdoubleconst 指针,即指针可以更改(即可以重新指向),但它所指向的值不可更改。但是 d1const

您的意思是:

const double* p = &d; // Line 1
const double* p1 = &d1; // Line 2

?

[See also this question from the C++ FAQ.]


我建议写成 double const *。它相当于 const double *,但您可以使用简单的规则“const适用于其前面的所有内容”,而无需额外的规则“在开头的const适用于最内层的类型”。 - Jan Hudec
@Jan:我理解你的逻辑,但最终这是个人偏好。我读上面的定义为“p是一个指向const double的指针”;对我来说,这一点都不令人困惑。 - Oliver Charlesworth
1
@Jan:个人认为按照您的方式教授的一个主要好处是,先写const会诱使人们认为typedef char *cptr; typedef const cptr ccptr;typedef const char *ccptr;相同。如果一直写typedef char const *ccptr;,他们就不太可能这样想。即便如此,在有自由的情况下,我仍然倾向于按照Oli的方式编写,并且在相关新闻中,也会写const int i = 0;而不是int const i = 0; - Steve Jessop
@Steve,@Oli:是的,我通常也会先写const。但这是一个特例,所以为了解释起见,我仍然建议从后缀开始。 - Jan Hudec
@Steve:但你把typedef放在前面。为什么?为什么不是char typedef * cptr;或者int volatile long typedef unsigned const long Foo;?语言并不在意。我喜欢看到限定符在前面,而typedef总是第一个。 (请注意:我并不是说将volatileconst组合起来很有意义...) - David Hammen
为什么不使用 char typedef * cptr;。因为 typedef 的语法本来就有点荒谬,我没有特别的愿望将其视为任何其他类型限定符,我更希望它像你一样引入定义。我提到的可能是采用 char const *ptr 的混淆并不适用于 typedef,因此我无法确定 char const typedef *ptr 有什么优势。因此,我不会以这种方式或任何其他排列方式编写它。 - Steve Jessop

2

如果您从右到左阅读声明,那么这将更容易:

double const *       p; // pointer to const double
const double *       p; // pointer to const double
double       * const p; // const pointer to double
double const * const p; // const pointer to const double

0

您可以通过以下方式轻松理解代码。

double const d1 = 30;
double* const p1 = &d1;

这里在第二行的问题是我们将一个const值d1分配给可以在将来更改的非const值。

如果我们理解右侧值的数据类型并将其赋给左侧值,那么这将更容易。

在我们的情况下,右侧数据类型可以被视为指向常量double的指针,而左侧是指向double的指针,这相矛盾,从而引发了编译器错误。


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