概述
this为const指针对象,指向当前实例对象,因此this的本质就是实例对象,non-static数据成员和non-static函数成员跟this相关联,而static数据成员和static函数成员跟this无关联,因此non-static数据成员和non-static函数成员属于实例对象成员,而static数据成员和static函数成员则不属于实例对象成员
同一类作用域内的所有成员(non-static数据成员,non-static函数成员,static数据成员,static函数成员)本质位于同一作用域,而对象名字定义search ignored对象名字的类型,因此同一类作用域内的所有成员名字不能重复(成员名字都是定义)
class CAnimal
{
public:
int getTotalAnimal();
public:
int totalAnimal;
public:
static int getTotalAnimal();
public:
static int totalAnimal;
};
注:编译error,getTotalAnimal和totalAnimal重复定义
成员指针
class CAnimal
{
public:
CAnimal() : mGroup(1) {}
public:
int mGroup;
public:
void init() { cout << "CAnimal::init()" << endl; }
public:
static int totalGroup;
public:
static int getTotalGroup() { cout << "CAnimal::getTotalGroup()" << endl; return totalGroup; }
};
int CAnimal::totalGroup = 5;
class CDog : public CAnimal
{
public:
CDog() : mGroup(2) {}
public:
int mGroup;
public:
void init() { cout << "CDog::init()" << endl; }
public:
static int totalGroup;
public:
static int getTotalGroup() { cout << "CDog::getTotalGroup()" << endl; return totalGroup; }
};
int CDog::totalGroup = 8;
void member_pointer()
{
cout << "-----static-----" << endl;
int* pAnimalStaticData = &CAnimal::totalGroup;
int (*pAnimalStaticFun)() = CAnimal::getTotalGroup;
cout << "totalGroup = " << *pAnimalStaticData << endl;
pAnimalStaticFun();
pAnimalStaticData = &CDog::totalGroup;
pAnimalStaticFun = CDog::getTotalGroup;
cout << "totalGroup = " << *pAnimalStaticData << endl;
pAnimalStaticFun();
cout << "-----non static-----" << endl;
int CAnimal::*pAnimalNonStaticData1 = &CAnimal::mGroup;
//int CAnimal::*pAnimalNonStaticData2 = &CDog::mGroup;
void (CAnimal::*pAnimalNonStaticFun1)() = &CAnimal::init;
//void (CAnimal::*pAnimalNonStaticFun2)() = &CDog::init;
int CDog::*pDogNonStaticData1 = &CAnimal::mGroup;
int CDog::*pDogNonstaticData2 = &CDog::mGroup;
void (CDog::*pDogNonStaticFun1)() = &CAnimal::init;
void (CDog::*pDogNonStaticFun2)() = &CDog::init;
CDog dog;
CDog* pDog = &dog;
CAnimal animal = dog;
CAnimal* pAnimal = &animal;
cout << "mGroup = " << animal.*pAnimalNonStaticData1 << endl;
cout << "mGroup = " << dog.*pAnimalNonStaticData1 << endl;
//cout << "mGroup = " << animal.*pDogNonStaticData1 << endl;
cout << "mGroup = " << dog.*pDogNonStaticData1 << endl;
//cout << "mGroup = " << animal.*pDogNonstaticData2 << endl;
cout << "mGroup = " << dog.*pDogNonstaticData2 << endl;
(animal.*pAnimalNonStaticFun1)();
(dog.*pAnimalNonStaticFun1)();
//(animal.*pDogNonStaticFun1)();
(dog.*pDogNonStaticFun1)();
//(animal.*pDogNonStaticFun2)();
(dog.*pDogNonStaticFun2)();
cout << "mGroup = " << pAnimal->*pAnimalNonStaticData1 << endl;
cout << "mGroup = " << pDog->*pAnimalNonStaticData1 << endl;
(pAnimal->*pAnimalNonStaticFun1)();
(pDog->*pAnimalNonStaticFun1)();
}
output:
-----static-----
totalGroup = 5
CAnimal::getTotalGroup()
totalGroup = 8
CDog::getTotalGroup()
-----non static-----
mGroup = 1
mGroup = 1
mGroup = 1
mGroup = 2
CAnimal::init()
CAnimal::init()
CAnimal::init()
CDog::init()
mGroup = 1
mGroup = 1
CAnimal::init()
CAnimal::init()
总结
- 从实例对象角度看,父类成员既属父类,也属子类,反之,子类成员只属子类,不属父类,从类作用域角度看,子类作用域嵌套于父类作用域,因此子类既可访问子类作用域,也可访问父类作用域,反之,父类只可访问父类作用域,不可访问子类作用域
- 对于static数据成员和static函数成员,类只有类作用域的含义,跟this无关联,因此引用static数据成员和static函数成员的指针定义跟普通非成员指针定义无区别
- 对于non-static数据成员和non-static函数成员,类既有类作用域的含义,也跟this相关联,因此引用non-static数据成员和non-static函数成员的指针定义跟普通非成员指针定义有区别,通过成员指针定义符(::*)定义non-static数据成员和non-static函数成员的指针,::*前标识类类型(表示指针引用成员与this相关联),::*后标识成员指针对象
- 成员指针运算符.*或->*,前者通过实例对象操作,后者通过实例对象指针操作,注意成员指针运算符和函数调用运算符的优先级关系,函数调用运算符优先级高于成员指针运算符优先级,通过成员指针运算符.*或->*访问成员指针时,把运算符前实例对象地址传给this隐含参数,因此子类可访问父类成员指针,父类不可访问子类成员指针,因为子类指针可隐式转换为父类指针,反之,父类指针不可隐式转换为子类指针
- 子类实例对象包含父类成员,因此子类成员指针既可引用子类成员,也可引用父类成员,反之,父类实例对象不包含子类成员,因此父类成员指针只可引用父类成员,不可引用子类成员,因此可通过子类实例对象访问父类成员指针(因为子类包含最终访问的成员),反之,不可通过父类实例对象访问子类成员指针(因为父类不一定包含最终访问的成员)
- 取static数据成员地址时,必须使用取地址操作符(&),如果不使用取地址操作符(&),获取的是static数据成员值,取non-static数据成员地址时,也必须使用取地址操作符(&),如果不使用取地址操作符(&),在类内部表示取特定类作用域内数据成员值
- 取static函数成员地址时,跟取普通非成员函数地址相同,取地址操作符(&)optional,可omit,取non-static函数成员地址时,必须使用取地址操作符(&),不可omit,此时取地址操作符(&)表示this隐含参数
- 取类成员(static数据成员,static函数成员,non-static数据成员,non-static函数成员)地址时,必须遵守对应类成员访问权限规则,否则就可通过类成员指针间接访问本不应该允许访问的成员