c++ 常成员函数 和 常对象

先明确几个概念:

1. 常对象只能调用常成员函数。

2. 普通对象可以调用全部成员函数。

3. 当对一个对象调用成员函数时,编译程序先将对象的地址赋给this指针,然后调用成员函数,每次成员函数存取数据成员时,由隐含使用this指针。
4. 当一个成员函数被调用时,自动向它传递一个隐含的参数,该参数是一个指向这个成员函数所在的对象的指针。
5. 在C++中,this指针被隐含地声明为: X *const this,这意味着不能给this 指针赋值;
   在X类的const成员函数中,this指针的类型为:const X* const, 这说明this指针所指向的这种对象是不可修改的(即不能对这种对象的数据成员进行赋值操作);
6. 由于this并不是一个常规变量,所以,不能取得this的地址。

如:

#include <iostream>

class A
{
public:
	A():mValue(0)
	{

	}
	void print()
	{
		std::cout<<"hello";
	}
	int GetValue()
	{
		return mValue;
	}
	int GetValue()const
	{
		return mValue;
	}

private:
	int mValue;
};

void test(A & const a)
{

}

int main()
{

	const A a;//const A* const this ;
	a.print(); //错误,将会提示 error C2662: “A::print”: 不能将“this”指针从“const A”转换为“A &”

	test(a); //error C2664: “test”: 不能将参数 1 从“const A”转换为“A &”
}

由于a是const对象,所以a只能调用类A中的常成员函数。

那么为什么会提示:“不能将this指针.......”的语句呢?

因为对于c++的成员函数(当然不是静态成员函数),都会含有一个隐藏的参数,对于上例A中的int GetValue()函数,在编译后会变成:

int GetValue(A * const this);  //不能修改this变量,但可以修改this指向的内容,即:this是常量指针。

而对于int GetValue()const ,编译后是:

int GetValue(const A* const this);

只所以this指针是const类型,因为在某次调用整个过程this指向都不允许改变(原因很简单,如果改变的话就不是这个对象调用的了)

从编译后的结果看就很清楚了, 因为a是const,所以其this指针就对应: const A* const this ;

而print函数被编译出来后对应的是void print(A* const this); 在进行参数匹配时, 所以就会提示 “不能将“this”指针从“const A ....."

this指针的出现就解释了,所有类A的对象都是公用一套代码模版,为什么各个对象在调用成员函数的时候不会乱套。

原来C++为成员函数提供了一个名字为this的指针,这个指针称为自引用指针。每当创建一个对象时,系统就把this指针初始化为指向该对象。每当调用一个成员函数时,系统就自动把this指针作为一个隐含的参数传给该函数。不同的对象调用同一个成员函数时,C++编译器将根据成员函数this指针所指向的对象来确定应该引用哪一个对象的数据成员。通常情况下,this指针是隐含存在的,也可以将其显示的表示出来(即如上例中的 this->mValue。不过this指针只能在类中使用)

还有就是  this指针是一个const指针,不能再程序中修改它或给它赋值;

c++ 常成员函数 和 常对象

时间: 2025-01-02 05:09:45

c++ 常成员函数 和 常对象的相关文章

c++常对象和常成员函数

常对象: 定义常对象的一般形式为: 类名 const 对象名[(实参表列)]; 也可以把const写在最左面: const 类名 对象名[(实参表列)]; 二者等价. 常对象的所有成员值都不能变,必须先初始化,不能调用非const成员函数 const成员函数: void get_time( ) const ; //将函数声明为const 不能改变类中的成员值们可以访问,若非要改变,可以把成员变量设置为mutable. const是函数类型的一部分,在声明函数和定义函数时都要有const关键字 不

C++ 常成员函数、常数据成员、常对象

常成员函数在声明和实现时都要带 const 关键字 常成员函数不能修改对象的数据成员,也不能访问类中没有用 const 声明的非常成员函数. 在任何函数中都不能对常数据成员赋值.对常数据成员初始化,只能通过构造函数的初始化列表. 常对象的数据成员在它的生存期内不会被改变,因此定义常对象时必须对其进行初始化.这里的初始化可以通过初始化列表完成,也可以通过构造函数函数体来完成. class Person { public: string name; Person() { name = "mollnn

C/C++中的常成员函数

代码: 1 #include <iostream> 2 3 using namespace std; 4 5 class A{ 6 public: 7 void func1(){ 8 cout<<"func1"<<endl; 9 } 10 void func1()const{ 11 cout<<"const func1"<<endl; 12 } 13 void func2()const{ 14 cout&l

const常对象成员与常成员函数

#include <iostream>#include <string>using namespace std;class pt{public: pt(int a,int b){this->x=a,this->y=b;} int getX() const {return this->x;} //此处必须加const(关键),否则A.getX()将无法正常调用 int getY() const {return this->y;} //因否则的话A.getX()

第五周项目1-体验常成员函数

设计平面坐标点类,计算两点之间距离.到原点距离.关于坐标轴和原点的对称点等.在设计中,由于求距离.求对称点等操作对原对象不能造成任何改变,所以,将这些函数设计为常成员函数是合适的,能够避免数据成员被无意更改. /* * Copyright (c) 2015,烟台大学计算机学院 * All right reserved. * 作者:邵帅 * 文件:Demo.cpp * 完成时间:2015年04月08日 * 版本号:v1.0 */ #include <iostream> #include <

项目一:体验常成员函数

[项目1-体验常成员函数] 设计平面坐标点类,计算两点之间距离.到原点距离.关于坐标轴和原点的对称点等.在设计中,由于求距离.求对称点等操作对原对象不能造成任何改变,所以,将这些函数设计为常成员函数是合适的,能够避免数据成员被无意更改. class CPoint { private: double x; // 横坐标 double y; // 纵坐标 public: CPoint(double xx=0,double yy=0); double Distance1(CPoint p) const

【项目1-体验常成员函数】

设计平面坐标点类,计算两点之间距离.到原点距离.关于坐标轴和原点的对称点等.在设计中,由于求距离.求对称点等操作对原对象不能造成任何改变,所以,将这些函数设计为常成员函数是合适的,能够避免数据成员被无意更改. ?class CPoint { private:   double x;  // 横坐标   double y;  // 纵坐标 public:   CPoint(double xx=0,double yy=0);   double Distance1(CPoint p) const; /

C++,常成员函数

#include <iostream> using namespace std; class Test { public: int x; int y; void const_m1() const; void const_m2() const; void m3(); void m4(); }; /** * //1常成员函数不能修改成员变量的值 * //2常成员函数只能调用常成员函数,不能调用普通成员函数 * //3普通成员函数可以调用常成员函数 */ void Test::const_m1(vo

C++中类的常成员函数

让一个成员函数带上常量性是什么意思呢?通常的答案是,一个常成员函数不会更改其class对象.这是一种平凡的表述,而编译器实现的手法也相当平凡. 任何非静态成员函数其实都被编译器隐式插入了一个指针类型的参数,以在调用时有一种指向class对象自身的途径.在函数内部,关键字this被用于给出该指针的值: T t; t.DoSomething(); //“this”就是&t T* pt = &t; pt->DoSomething //“this”就是pt 对于T类型的非常成员函数而言,其t