对象指针
每个变量都占有一定的内存空间,对象同样也需要占用内存空间。对象有数据成员和函数成员两种成员,但是实际上只有对象的数据成员会占用内存,函数成员则不会。我们可以通过对象名引用对象,也可以通过对象地址访问对象。对象指针就是存储对象地址的变量。声明对象指针的方式与一般的指针类似:
类名 *对象指针名;
用对象指针访问对象的公有成员的形式为:
对象指针名->公有成员名;
#include <iostream>
using namespace std;
class CStudent
{
public:
CStudent(int nAge=15) { m_nAge = nAge; } // 构造函数
int GetAge() { return m_nAge; } // 内联函数,返回m_nAge
private:
int m_nAge; // 私有数据
};
int main()
{
CStudent student(17); // 声明对象student并对其初始化
CStudent *ptr; // 声明对象指针
ptr = &student; // 初始化对象指针
cout << student.GetAge() << endl; // 通过对象名访问对象的成员
cout << ptr->GetAge() << endl; // 通过对象指针访问对象的成员
return 0;
}
- 跟一般指针一样,对象指针在使用之前也必须先赋值,因为它必须先明确指向一个对象才能正常使用,否则可能会由于被赋与了随机值而有可能访问到重要地址破坏系统数据。
this指针
this指针实际上就隐含于类的成员函数中,它指向成员函数正在操作的对象。构造函数和析构函数也不例外,也同样隐含了this指针。它也是一个指针,只是有点特殊。
比如上面的CStudent类的成员函数GetAge中的语句:return m_nAge;对于编译器来说相当于执行return this->m_nAge;。为什么要有这个this指针呢?因为在执行这条语句时编译器需要知道返回的m_nAge到底属于哪一个对象,编译器事先已经把对象地址赋给this指针,调用成员函数操作数据成员时就隐含使用了这个this指针,这样就确定了访问的m_nAge属于哪个对象。\
使用: 一般在软件开发中不会直接用到this指针访问数据成员,有时需要将此对象作为参数传递给某个函数时会使用this指针,亦或是写程序时忘记某个函数名,输入this->后vs2010会提示出所有成员函数。
指向类的非静态成员的指针
也可以对类的共有数据成员和共有函数成员通过指针进行访问。但是在没有确定对象的时候,声明和赋值的数据成员和函数成员指针只是确定了一个指针偏移值,而没有指针的初始地址值,只有确定类的对象之后才能通过共有数据成员和共有函数成员指针对类中的公有元素进行访问。
声明指向非静态成员的指针的语法形式为:
类型说明符 类名::*指针名; // 声明指向公有数据成员的指针
类型说明符 (类名::*指针名)(形参表); // 声明指向公有成员函数的指针
先声明再赋值,然后才能引用。指针赋值语句为:
指针名 = &类名::数据成员名;
指针名 = &类名::函数成员名;
通过对象来访问数据:
对象名.*指向数据成员的指针名
对象指针名->*指向数据成员的指针名
(对象名.*指向成员函数的指针名)(形参表)
(对象指针名->*指向成员函数的指针名)(形参表) //需要注意声明的函数指针的返回值和形参表的数据类型必须和访问的共有函数成员一致
int main()
{
CStudent student(17); // 声明对象student并对其初始化
CStudent *ptr; // 声明对象指针
int (CStudent::*pGetAge)();// 声明指向成员函数GetAge的指针
pGetAge = &CStudent::GetAge;// 为pGetAge赋值
ptr = &student; // 初始化对象指针
cout << student.GetAge() << endl; // 通过对象名访问成员函数
cout << ptr->GetAge() << endl; // 通过对象指针访问对象的成员函数
cout << (student.*pGetAge)() << endl; // 通过成员函数指针访问成员函数
return 0;
}
指向类的静态成员的指针
对于类的静态成员,我们可以用普通指针存放它的地址,通过普通指针访问它。
#include <iostream>
using namespace std;
class CStudent
{
public:
CStudent(int nAge=15) { m_nAge = nAge; m_nCount++; } // 构造函数
CStudent(CStudent &stu); // 拷贝构造函数
int GetAge() { return m_nAge; } // 内联函数,返回m_nAge
static int m_nCount; // 静态数据成员声明
private:
int m_nAge; // 私有数据
};
CStudent::CStudent(CStudent &stu)
{
m_nAge = stu.m_nAge;
m_nCount++;
}
int CStudent::m_nCount = 0; // 静态数据成员初始化
int main()
{
int *pCount = &CStudent::m_nCount; // 声明一个int型的指针,指向静态数据成员m_nCount
CStudent student1(17); // 声明对象student1并对其初始化
cout << "student1:" << student1.GetAge() << endl;
cout << "student id=" << *pCount << endl; // 通过指针访问静态数据成员
CStudent student2(student1); // 声明对象student2并用student1初始化它
cout << "student2:" << student2.GetAge() << endl;
cout << "student id=" << *pCount << endl; // 通过指针访问静态数据成员
return 0;
}