C++:将指向 const 对象的指针复制到非常量对象指针

C++: Copying pointer to const object into non-const object pointer

在我的自定义 class 中,当我将输入变量指针声明为常量并将其复制到非常量成员变量指针时出现错误。

我得到的错误是:

Cannot initialize a member subobject of type 'Position *' with an lvalue of type 'const Position *'

为什么会这样?为什么这与另一个成员变量(_attack)不一致?它只是复制指针(地址)的值,就像复制 int 的值一样(_attack)。

class Creature
{
private:
  int _attack;
  Position* _position;
public:
  Creature(const int attack, const Position* position)
      : _attack{attack}, _position{position} // ERROR: Cannot initialize a member subobject of type 'Position *' with an lvalue of type 'const Position *'
  {}
};

第一个参数不引用构造函数范围之外的任何内容,因为它只是一个副本。这种情况下的 const 只是说您的构造函数本身不允许更改 attack.

的值

第二个参数是一个指向const Position的指针。如果可以将其分配给非常量 Position*,则可以通过非常量指针改变该位置。如果这是允许的,那么如果有人有一个他们不想被你的构造函数改变的 Position 指针,就没有办法创建你的 class 的实例。

请注意,您可以将第二个参数更改为 Position* const position,从而使第二个参数的行为与第一个参数相同。这使得指针 const 但不是它指向的对象。

参见 this 相关问题。

指针有两种“类型”const。他们是

const T * pointer_name

T * const pointer_name

也可以组合成

的第三种也是最后一种形式
const T * const pointer_name

对于第一个,您正在创建一个指向 const T 的指针。这就是你在构造函数中所拥有的。这违背了 _position 的类型,即 T *,或者更确切地说,是指向非常量 T 的指针。这就是您收到错误的原因。您不能将指向非常量 T 的指针的值分配给指向 const T.

的指针

使用第二种形式,您的代码可以编译,因为现在您没有指向 const T 的指针,而是有一个指向 Tconst 指针。两个指针都指向一个非常量的东西,所以可以将一个赋值给另一个

这与 attack 发生的情况相同。虽然它可能是常量,但您仍然可以复制它的值并将其放入另一个对象中。

最后一种形式是指向 const Tconst 指针,并且出于与第一种形式不起作用的原因相同的原因在这里不再起作用。


这也有点进入东海岸 vs 西海岸 const 风格。有了上面的west-coast style,有时候就不太容易理解这个类型了。相反,你可以使用像

这样的东海岸风格
T const * pointer_name
T * const pointer_name
T const * const pointer_name

现在他们都从右到左阅读确切的类型。

对于构造函数的 attack 参数(声明为 const),您正在 复制 给成员变量的值( _attack), 即不是 const;但是,该成员变量的后续修改不会更改传递参数的值,因此您并没有“违背承诺”。

然而,在position参数的情况下,情况就大不相同了:这里的const限定符声明它指向一个不可修改的对象;但是,如果您要将该指针的值(即地址)复制到非常量成员变量,那么您将允许修改引用的对象。所以,编译器(正确地)告诉你不能那样做。

如果您实际上想要传递一个指针,它是一个不可变的地址,但是传递给一个可以改变,那么需要在构造函数的参数中移动const关键字:

    Creature(const int attack,  Position* const position) // POINTER is const, POINTEE is not!