假设employee是一个类.... print是它的非静态成员函数,它打印其私有数据成员的值x ...现在我读到如果print是一个常量函数,则该指针传递给它编译器的类型为
const employee * const
如果print是非常量函数,则该指针的类型为
employee * const
....现在的问题是我还没有将类员工的对象声明为常量,那么如果将print声明为常量函数,那么'this'如何指向一个常量的employee对象....
答案 0 :(得分:2)
const employee* const
是指向const员工的const指针。与employee* const
对比,this
是指向非const员工的const指针。
在前一种情况下,this
和它指向的任何内容都不能被修改。在后一种情况下,this
可能不会被修改,但您可以修改{{1}}指向的任何内容。
答案 1 :(得分:2)
考虑冰淇淋甜筒。假设你去冰淇淋店订购“香草锥”。你会得到一个带有一勺香草冰淇淋的圆锥。然后你可以在上面添加一个樱桃,但它仍然是你订购的 - 一个香草锥。
物体有点像冰淇淋蛋筒。常数就像樱桃一样。您可以在不更改对象本身的情况下将constness添加到对象:
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引用的标准段落:
1类型“指向cv1 T的指针”的右值 可以转换为类型的右值 如果“cv2 T”更多,则指向“cv2 T” cv-qualified比“cv1 T。”
答案 2 :(得分:1)
将const employee*
指向非const对象没有问题。将employee*
指向const对象是有问题的并且被语言规则阻止(直到你开始使用const_cast)。
答案 3 :(得分:1)
如果将print声明为常量函数,那么'this'如何指向一个常量的employee对象....
在非静态成员函数const
的末尾使用print
修饰符时,无法在其中修改调用它的对象的状态(使用const_cast
时的状态类型转换是可能的,并且使const
修饰符非常用于成员函数。这就是const
在函数末尾的重要性。
答案 4 :(得分:1)
答案 5 :(得分:0)
将指针声明为const T* p;
不意味着p
指向常量T
。这意味着p
指向T
,它可以是常量也可以是非常量,并且无法通过p
进行更改。