一、类成员指针
1.概念
类成员指针指向的是类的非static成员,因为类的static成员是所有类对象共有,所以static成员的指针和普通指针没有区别
2.成员变量指针
示例
class test
{
public:
test(){}
~test(){}
int pub;
private:
int pri;
};
int main(int argc, char const *argv[])
{
int test::*pi=&test::pub;
test t;
t.*pi=10;
cout<<t.pub<<endl;
return 0;
}
上述代码中pi就是个test的成员变量指针,成员变量指针的读法依旧是从右到左,首先*pi知道pi是个指针,::test知道该指针指向test对象中的成员,int表明该指针指向test对象中的int成员

因为成员变量指针是个指针,解引用需要用*,但是该指针又指向某个类的成员变量。所以不能直接解引用类成员指针,必须用类的对象,指针或者引用访问该成员变量指针解引用出来的成员变量
如果把t.*pi=10;写成*pi,将会出错

提示解引用无效,因为没有指定访问该解引用的类的对象,指针或者引用
成员变量有访问权限,所以,成员变量的指针也受访问权限修饰符的影响,上述代码中,不能在主函数中让一个成员变量指针指向&test::pri,因为pri是private的,否则会出现如下错误

对于私有的成员变量指针,只能在类的成员和友元中使用
因为成员变量一般是私有的,所以一般不能直接获取成员指针,需要一个返回成员指针的函数
示例
class test
{
public:
test(){}
~test(){}
int pub;
int test::*funcpri();
private:
int pri;
};
int test::*test::funcpri()//返回一个成员变量指针的函数
{
return &test::pri;
}
int main(int argc, char const *argv[])
{
test t;
int test::*p=t.funcpri();
t.*p=10;
cout<<t.*t.funcpri()<<endl;//打印对象t的pri成员
return 0;
}

3.成员函数指针
成员函数指针用的比较多的就是用作Qt的信号槽,和成员变量指针、函数指针类似
示例
connect(pstartbtn_, &QPushButton::pressed, this, &MainWindow::onstartbtnclicked);
connect(pkeyboardbtn_, &QPushButton::pressed, this, &MainWindow::onkeyboardclicked);
上述代码中,connect的第2个和第4个参数就是成员函数指针,成员函数不能自动转化为成员函数指针,所以必须在成员函数前加上&,得到的才是成员函数指针
和成员变量一样,因为成员函数指针是个指针,解引用需要用*,但是该指针又指向某个类的成员函数。所以不能直接解引用类的成员函数指针
必须用类的对象,指针或者引用访问该成员函数指针解引用出来的成员函数
示例
class test
{
public:
test(){}
~test(){}
void func() const{};
};
int main(int argc, char const *argv[])
{
test t;
void (test::*pf)() const=&test::func;
(t.*pf)();
return 0;
}

上述代码中第12行中,(test::*pf)中的括号和后面的const必不可少
此外。13行中的(t.*pf)();不能写成t.*pf();当把括号去掉后,编译器就认为要调用一个名字叫pf的成员函数,然而pf并不是成员函数,于是报错

成员函数有访问权限,所以,成员函数的指针也受访问权限修饰符的影响,同成员变量
想通过成员函数指针进行函数调用,必须通过将该成员函数指针绑定到特定的对象、指针或引用上。所以,单独的成员函数指针并不是可调用对象,所以,不能直接将单独的成员函数指针作为实参传入一个函数
示例
int main(int argc, char const *argv[])
{
vector<string> vstr={"123", "456", "789"};
bool (string::*p)() const= &string::empty;
find_if(vstr.begin(), vstr.end(), p);
return 0;
}

所以,当使用函数指针作为参数时,不要把成员函数指针当做实参,因为成员函数指针不可调用
二、嵌套类
顾名思义就是一个类定义在另一个类的内部。嵌套类的名字只在外层类中可见,在其他地方不可见。虽然嵌套类在另一个类中定义,但是和外层类没有任何关系,只不过作用域仅限于外层类
示例
class one
{
public:
one(){}
~one(){}
class two
{
public:
two(){}
~two(){}
void func2();
int twomem;
};
};
void one::two::func2() {}
int main(int argc, char const *argv[])
{
//two t;
//one t;
//t.func2();
return 0;
}
two是one的嵌套类,当实现two中的func2时,func2的作用域也是从外到内一层一层写。因为two的作用域仅限于one,所以20行的代码是错误的,因为one和two没有任何关系,所以2122行的代码是错误的

因为嵌套类的作用域仅限于外层类。所以,嵌套类一般用于外层类的实现
三、union
union有多个数据成员,但是这些数据共用内存,同一时刻只有一个成员有值
union在嵌入式开发中非常常用,经常和char数据一起使用,用来定义收发数据的数据格式
示例
union uploaddata
{
unsigned char buffer[20];
struct sensorstr
{
unsigned int Header;
float X_speed;
float Y_speed;
float Z_speed;
unsigned char End_flag;
}sensordata;
};
union中buffer的大小正好就是sizeof(sensordata),buffer和sensordata共用一块内存,当收到buffer中的数据时,可以通过struct对buffer中的数据进行解析,当发送数据时,也可以通过对struct的成员进行赋值,然后将buffer发送出去
参考
《C++ Primer》
欢迎大家评论交流,作者水平有限,如有错误,欢迎指出
本文详细讲解了类成员指针的概念,包括成员变量指针和成员函数指针的使用、访问权限与限制,以及嵌套类的作用和应用场景。通过实例演示,深入理解指针在C++中的实际操作。

被折叠的 条评论
为什么被折叠?



