此指针作为指向对象的指针

this pointer as a pointer to objects

本文关键字:指针 对象      更新时间:2023-10-16

假设员工是一个类....print 是其非静态成员函数,它打印其私有数据成员 x 的值...现在我读到,如果 print 是一个常量函数,编译器传递给它的 this 指针的类型是

常量员工* 常量

如果 print 是一个非常量函数,则此指针的类型为

员工* 常量

....现在的问题是我没有将类员工的对象声明为常量,那么如果将打印声明为常量函数,"这"怎么能指向常量员工对象......

考虑冰淇淋蛋筒。 假设你去冰淇淋店点了一个"香草蛋筒"。 你会得到一个甜筒和一勺香草冰淇淋。 然后你可以在上面加一个樱桃,但它仍然是你订购的,虽然 - 一个香草甜筒。

物体有点像冰淇淋甜筒。 恒常就像上面的樱桃。 您可以在不更改对象本身的情况下向对象添加恒常性:

class Foo 
{ 
public: 
  void DoIt() {}; 
} foo;
Foo* regular_foo = &foo; // OK
const Foo* const_foo = &foo; // Also OK

回到冰淇淋店。 这次点了一个带洒的香草蛋筒。 他们给你一个甜筒,上面放着1勺香草冰淇淋和一些糖果。 现在,如果不更改订购的内容,您将无法取下洒水。 如果你取下洒水,你不会有一个"带洒的香草锥",你只会有一个香草锥。

class Foo 
{ 
public: 
  void DoIt() {}; 
};
const Foo foo;
Foo* regular_foo = &foo; // Not OK!
const Foo* const_foo = &foo; // But this is OK

编辑:

为了更严格地处理我上面的类比,您可以阅读@Potatoswatter引用的标准中的段落:

4.4 资格转换 [转换质量]

1 "指向 cv1 T 的指针"类型的右值 可以转换为类型的右值 "指向 cv2 T"的指针,如果"cv2 T"更多 CV合格比"cv1 T"。

const employee* const是指向常量员工的常量指针。将其与employee* const形成对比,后者是指向非常量员工的常量指针。

在前一种情况下,this及其指向的任何内容都不得修改。在后一种情况下,this可能不会被修改,但您可以修改this指向的任何内容。

让一个指向非常量对象的const employee*没有问题。 让一个指向 const 对象的employee*是有问题的,并且被语言规则阻止(直到你开始使用 const_cast(。

如果打印被声明为常量函数,"这"怎么能指向常量的员工对象......

使用非静态成员函数末尾的const修饰符print,调用它的对象的状态不能在其中修改(使用const_cast类型转换是可能的,这使得成员函数无法使用const修饰符(。这就是函数末尾const的意义所在。

const称为 cv 限定符; const employee *employee *符合简历条件。该标准的§4.4/1说

如果"cv2 T">

比"cv1 T"更符合 cv1 T,则可以将类型为"指向 cv1 T"的 prvalue 转换为类型为"指向 cv2 T"的 prvalue。

用简单的英语来说,const只是保证你不会尝试通过该指针更改对象。添加该保证并进一步限制自己总是可以的。

仅当您尝试消除此类保证时,才会出现问题,这就是为什么您不能使用非常量方法(并获取非常量this(从常量对象。

将指针声明为 const T* p;并不意味着p指向常量T。这意味着p指向一个T,它可以是常数或非常数,并且不能通过p来改变。