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

C++ 此指针作为指向对象的指针,c++,C++,假设employee是一个类…print是它的非静态成员函数,它打印它的私有数据成员x的值…现在我读到,如果print是一个常量函数,编译器传递给它的指针的类型是 康斯特雇员*康斯特 如果print是一个非常量函数,则该指针的类型为 雇员*const …现在的问题是,我没有将employee类的对象声明为常量,因此如果print被声明为常量函数,“this”如何指向常量employee对象…让常量employee*指向非常量对象没有问题。让一个employee*指向一个const对象是有问题的,

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

康斯特雇员*康斯特

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

雇员*const


…现在的问题是,我没有将employee类的对象声明为常量,因此如果print被声明为常量函数,“this”如何指向常量employee对象…

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

const employee*const
是指向const employee的const指针。将其与
employee*const
进行对比,后者是指向非const雇员的const指针

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

如果print被声明为常量函数,“this”如何指向常量employee对象


在非静态成员函数
print
末尾使用
const
修饰符时,无法在其中修改调用它的对象的状态(但使用
const\u cast
typecast时,这是可能的,这使得成员函数不能使用
const
修饰符)。这就是函数末尾的
const
的意义所在

常量称为cv限定符
const employee*
employee*
更符合简历要求。本标准第4.4/1条规定:

如果“cv2 T”比“cv1 T”更符合cv条件,则“指向cv1 T的指针”类型的PR值可转换为“指向cv2 T的指针”类型的PR值

简单地说,
const
保证您不会试图通过该指针更改对象。添加这种保证并进一步限制自己总是好的


只有当您试图消除这种保证时,才会出现问题,这就是为什么您不能从const对象使用非const方法(并获取非const
this
)的原因。

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

class Foo 
{ 
public: 
  void DoIt() {}; 
};

const Foo foo;
Foo* regular_foo = &foo; // Not OK!
const Foo* const_foo = &foo; // But this is OK
物体有点像冰淇淋筒。恒久如顶上的樱桃。可以在不更改对象本身的情况下向对象添加常量:

class Foo 
{ 
public: 
  void DoIt() {}; 
} foo;

Foo* regular_foo = &foo; // OK
const Foo* const_foo = &foo; // Also OK
回到冰淇淋店。这次点一个香草蛋卷,上面撒些香料。他们给你一个蛋卷,上面撒上一勺香草冰淇淋和一些糖果。现在,如果不更改您点的菜,您就无法取下洒布。如果你把洒的东西去掉,你就不会有“香草甜筒加洒”,你只会有一个香草甜筒

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资格转换[conv.qual] 1“指向cv1 T的指针”类型的右值 可以转换为类型为的右值 如果“cv2 T”更大,“指向cv2 T的指针” cv比“cv1 T”合格


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

+1个例子来改变:
int i=42,j=314;int*const that=&i*这等于43;that=&j;//被编译器拒绝
在对原始帖子的评论中,请参阅@Fredriffolf对我和类似答案的反驳。简而言之,
不是
employee*const
,它是
employee*
类型的右值。“谢谢,”弗雷德说!
这个
指针本身不是
常量
,它是一个右值。@FredOverflow--我想你是对的,这使得OP的书错了,我的答案也错了。你有章节来支持你的说法吗?@Rob:当然,9.3.2§1说“关键字
this
是一个prvalue表达式,其值是调用函数的对象的地址。类
X
的成员函数中
this
的类型是
X*
。如果成员函数被声明为
const
,则其类型为
const X*
“您刚才让我去冰箱买了一些香草冰淇淋。Yum!
+1
,冰淇淋。