【c++类和对象】——this指针和成员方法之间的关系、指向类成员的指针

一、this指针和成员方法之间的关系

就拿上一篇我们写过的商品类来说,我们都知道里面的所有成员方法都是普通的成员方法。
商品类代码实现如下:

class CDate
{
public:
	CDate(int y, int m, int d)
	{
		_year = y;
		_month = m;
		_day = d;
	}
	void show()
	{
		cout << _year << "/" << _month << "/" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
class CGoods
{
public:
	CGoods(const char* n, int a, double p,int y,int m,int d):_data(y,m,d)
	{
		strcpy(_name, n);
		_amount = a;
		_price = p;
	}
	void show()
	{
		cout << "name: " << _name << endl;
		cout << "amount:" << _amount << endl;
		cout << "price:" << _price << endl;
		_data.show();
	}
private:
	char _name[20];
	int _amount;
	double _price;
	CDate _data;
};

1、普通的成员方法

普通的成员方法都得由对象来调用,因为编译过后会把对象的地址当做实参传给函数,在编译过程中这些成员方法就会多加一个this形参变量来接收他的调用对象。
他有如下特点:

  • 属于类的作用域
  • 调用该方法时需要依赖一个对象(常对象是无法调用)
  • 可以任意访问对象的私有成员变量 不考虑protected,只考虑public和private

2、静态成员方法

如果我们要在之前说的商品类里面,要添加一个需求——统计所有商品的总数量

改进一:构造函数里面添加一个_count++;记录所有产生的新对象的数量

CGoods(const char* n, int a, double p, int y, int m, int d)
		:_data(y, m, d)
		{
			strcpy(_name, n);
			_amount = a;
			_price = p;
			_count++;
		}

改进二:添加一个静态成员方法,打印所有商品共享的信息

static void showCGoodsCount()
	{
		cout << "所有商品的种类数量是: " << _count << endl;
	}

改进三:在private里面定义一个一个静态的成员变量。

private:
	char _name[20];
	int _amount;
	double _price;
	CDate _data;
	static int _count;

此处只是声明,要在类外定义并且初始化.不属于对象,而是属于类级别。不占用对象内存,在.data段

改进三:要在类外进行初始化

int CGoods::_count = 0;

静态成员方法特点:不会生成this形参

  • 属于类的作用域

  • 用类名作用域来调用方法

  • 可以任意访问对象的私有成员,仅限于不依赖对象的成员(只能调用其它的static静态成员)

    普通成员方法和静态成员方法的区别:
    前者有一个CGoods *this,后者没有this指针不需要接收一个对象的地址调用

3、常成员方法

在以上的商品类的基础上增加一个需求,要在main函数里面声明一个商品对象,该商品只能查看

int main()
{
const CGoods good5("非卖品商品5",100, 35.0, 2019, 5, 12);
	good5.show();
	return 0;
}

注意,此处调用的普通方法show()会出错,因为常对象调用普通方法 CGoods::show(&good5) const CGoods*-> CGoods *this错误,常对象调用的方法一定要是常方法

改进一:定义一个show的常方法

void show() const//const CGoods *this
	{
		cout << "name: " << _name << endl;
		cout << "amount:" << _amount << endl;
		cout << "price:" << _price << endl;
		_data.show();
	}

时间调用的show也应该是常方法

void show() const
	{
		cout << _year << "/" << _month << "/" << _day << endl;
	}

常成员方法,与普通成员方法重载 普通对象和常对象都可以调用.只要是只读操作的成员方法,一律实现成const常成员方法

常成员方法特点:生成const CGoods *this

  • 属于类的作用域
  • 调用依赖一个对象,普通对象或者常对象都可以
  • 可以任意访问对象的私有成员,但是只能读,不能写

二、指向类成员的指针

我们有这样一个类:

class Test
{
public:
	void func() { cout << "call Test :: func" << endl; }
	static void static_func() { cout << "Test::static_func" << endl; }
	int ma;
	static int mb;
};
int Test::mb;

当我们要定义一个指针指向成员变量或方法应该如何实现呢?
注意!指针前面都要加一个类作用域
(1)指向普通成员变量的指针

Test t1;
	Test* t2 = new Test();
int Test::* p = &Test::ma;
	t1.*p = 20;
	cout << t1.*p << endl;

	t2->*p = 30;
	cout << t2->*p << endl;
	delete t2;

(2)指向静态成员变量的指针,不依赖对象

int* p1 = &Test::mb;
	*p1 = 40;
	cout << *p1 << endl;
	

(3)指向成员方法的指针(普通成员方法是一定要依赖对象的)

void (Test :: * pfunc)() = &Test::func;
	(t1.*pfunc)();
	(t2->*pfunc)();
发布了98 篇原创文章 · 获赞 9 · 访问量 3672

猜你喜欢

转载自blog.csdn.net/qq_43412060/article/details/105098230