为什么允许在初始化列表中从const指针到const到const指针到非常量的转换

林力克斯

我阅读了有关为什么C ++没有const构造函数的问题。

我仍然很困惑为什么该程序可以编译。我试图对这个问题发表自己的看法,但我不知道为什么要删除它。所以我不得不再次问这个问题。

这是程序

class Cheater
{
public:
    Cheater(int avalue) :
    value(avalue),
    cheaterPtr(this) //conceptually odd legality in const Cheater ctor
    {}

    Cheater& getCheaterPtr() const {return *cheaterPtr;}
    int value;
private:
    Cheater * cheaterPtr;
};
int main()
{
    const Cheater cheater(7); //Initialize the value to 7

 //   cheater.value                 = 4;    //good, illegal
    cheater.getCheaterPtr().value = 4;    //oops, legal
    return 0;
}

我的困惑是:

const Cheater cheater(7) 在其构造函数中创建一个const对象作弊者

  Cheater(int avalue) :
    value(avalue),
    cheaterPtr(this) //conceptually odd legality in const Cheater ctor
{}

'this'指针用于初始化cheaterPtr

我认为这是不对的。cheater是一个const对象,其指针应类似于:const Cheater* const this;这意味着它本身的指针和该指针所指向的对象都应为const,我们既不能更改指针的值也不能修改指针所指向的对象。

但是对象cheatercheaterPtr成员就像Cheater* const cheaterPtr这意味着指针是const,但是它指向的对象可以是非const。

众所周知,指针到常量到指针到非常量的转换是不允许的:

int i = 0;
const int* ptrToConst = &i;
int * const constPtr = ptrToConst;  //  illegal. invalid conversion from 'const int*' to 'int*'

初始化列表中如何允许从指针到常量到指针到非常量的转换?到底发生了什么?

这是我尝试提供给原始帖子的构造函数中有关“ constness”的描述:

“与其他成员函数不同,构造函数可能不会声明为const。当我们创建类类型的const对象时,直到构造函数完成对象的初始化之后,该对象才会假定其'constness'。因此,构造函数可以写入const在施工过程中的物体。”

--C ++ Primer(第5版)P262 7.1.4构造函数

WhozCraig

您的假设是不正确的。一次带他们一个,第一个代码注释。

class Cheater
{
public:
    Cheater(int avalue) :
        value(avalue),
        cheaterPtr(this) // NOTE: perfectly legal, as *this is non-const
                         // in the construction context.
    {}

    // NOTE: method is viable as const. it makes no modifications
    //  to any members, invokes no non-const member functions, and
    //  makes no attempt to pass *this as a non-const parameter. the
    //  code neither knows, nor cares whether `cheaterPtr`points to
    //  *this or not.
    Cheater& getCheaterPtr() const {return *cheaterPtr;}

    int value;

private:
    Cheater * cheaterPtr; // NOTE: member pointer is non-const.
};


int main()
{
    // NOTE: perfectly ok. we're creating a const Cheater object
    //  which means we cannot fire non-const members or pass it
    //  by reference or address as a non-const parameter to anything.
    const Cheater cheater(7);

    // NOTE: completely lega. Invoking a const-method on a const
    // object. That it returns a non-const reference is irrelevant
    // to the const-ness of the object and member function.    
    cheater.getCheaterPtr().value = 4;

    return 0;
}

你说:

我认为这是不对的。作弊者是一个const对象,其指针应类似于:const Cheater* const this

cheater 正在 const 建设中构造过程中,它必须是非常量的此外,构造函数不(也无法)知道调用方已指示对象为const它所知道的只是构造对象的时间,这就是它的作用。此外,施工&cheaterconst Cheater *const在这种情况下,将实际的指针设为var本身也是完全不适用的。

接着...

...对象作弊者的cheaterPtr成员类似于 Cheater* const cheaterPtr;

实际上,这是一种非常准确的描述方式。因为cheaterconst其成员是为好,这意味着cheaterPtr构件const; 不是它所指向您无法更改指针值,但是由于它不是指向const对象的指针,因此您可以自由地使用该指针来修改其指向的对象,在这种情况下恰好是this

如果你想指针和指向的对象为const您已经对子级声明它const Cheater *cheaterPtr;的成员列表。(顺便说一句,顺便说一句,它只会通过getCheaterPointer()无效命令使该可变操作生效。它也必须返回a const Cheater*,这意味着分配当然会失败。

简而言之,此代码完全有效。什么你希望看到(的建设意识呼叫者常量性)不是语言的一部分,而事实上,如果你想你的构造有纬度...好,它不能是结构

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么const指针差异不能用作静态变量的初始化程序?

用const指针初始化const struct

为什么C不允许从char **到const char * const *的隐式转换(而C ++允许)?

为什么从char ***到char * const **的转换无效?

为什么允许从const到非const的隐式转换?

强制转换中的中间指针必须是“ const限定”的-为什么?

从'const char **'到'char * const *'的无效转换

为什么此指针到常量指针的分配是非法的?

为什么将const std :: string&传递给构造函数不允许您将其绑定到初始化程序列表中的const std :: string&成员变量?

初始化并打印const char指针

使用函数中的const指针进行编译时初始化

为什么我得到“从const指针到指针的无效转换?”

警告:初始化会从指针目标类型中丢弃“ const”限定符

通过memcpy将“指向const的指针”复制到“指向非const的指针”

是什么原因初始化或为C中的char指针或C ++中的const char指针分配空字符串文字?

为什么在用指针编译时不能分配const初始化

初始化const指针为null时为什么没有警告或错误?

初始化const指针-C ++中的初始化列表

为什么不能用其他静态const指针初始化静态const指针?

为什么在片段中从char *到std :: string的转换比向const char *的转换更可取?

如何正确地声明从非常量迭代器到指针的const指针

通过非常量指针修改const int

常量与数组到指针的转换

如何初始化指向未知大小的const数据的const指针(需要alloc)

为什么首先要允许从非const到const的隐式转换?

从'const char *'到struct中的'char'/未初始化const成员的无效转换

从“char”到“const char*”的无效转换[-fpermissive](idk为什么)

初始化从指针目标类型中丢弃“const”限定符

const 指针 - 为什么不允许使用 const 指针