多重继承和类型转换,以及类成员指针相关
【摘要】 多重继承和类型转换,以及类成员指针相关
1.多重继承
多重继承的话,构造函数的顺序,是按照继承时候写的顺序来
能用单一继承的问题不用多重继承
class A : virtual public Grand(—)虚继承,作用是不让派生类拥有多个基类的部分,其中virtual和public可以互换位置
一旦Grand成为虚基类后,Grand类的初始化工作就不会再由它的直接子类A,A2来初始化了,而是最下层的来初始化
2.类型转换构造函数
类型转换构造函数,把别的转为这个类的类型
class TestInt
{
public:
TestInt(int x = 0) : m_i(x)
{
if(m_i < 0) m_i = 0;
if(m_i > 100) m_i = 100;
}
public:
int m_i;
}
在main主函数中,加入如下代码
TestInt ti = 12;//隐式类型转换,将数字转化为TestInt对象(调用类型转换构造函数)
TestInt ti2(22);//调用类型转换构造函数,但这个不是隐式类型转换
如果不希望发生隐式类型转换,可以增加explicit,这是禁止隐式转换
explicit TestInt(int x = 0) : m_i(x)
既然用了禁止隐式,则代码也要改改
TestInt ti = TestInt(12);
接下来是类型转换运算符,可以当作是类的一个成员函数,把类转为别的类型
public:
operator int () const
{
return m_i;//返回的就是一个int类型,可以把该类对象转换为int类型
}
在main主函数中,写这个
ti2 = 6;
int k = ti2 + 5; k=11,这里调用operator int()将ti2转为int,结果为6,在和5做加法,结果给k
int k2 - ti2.operator int() + 5;.//也可以显式调用,注意写法,没有形参,所以括号内为空
无论把其他类型转为类类型,还是反过去转换,尽量都少用,因为代码难读懂,并且有二义性,二义性就是怎么样都行,所以编译器不知道怎么做了
例如
operator int() {}
operator double() {}
此时在main主函数中
TestInt aa;
int abc = aa + 12; //会产生二义性错误
3.类成员指针
3.1.对于普通成员函数
定义普通成员函数指针: 类名::*函数指针变量名字
获取类成员函数地址: &类名::成员函数名
class Test
{
public:
void myfunc(int temp) { };
}
在main主函数中
void (Test:: *pfunc)(int); //类成员函数指针变量的定义,变量名字是pfunc
pfunc = &Test::myfunc; //类成员函数指针变量被赋值
对于类对象调用成员函数: 类对象名.*函数指针变量名字
对于类对象指针调用成员函数: 指针名->*函数指针变量名字
例如
CT ct, *pct;
pct = &ct;
(ct.*pfunc)(100);
(pct->*pfunc)(200);
3.2.对于虚成员函数
和普通成员函数调用方法一样,只不过这个指针指向的是虚函数地址,因为类中有虚函数,会产生一个虚函数表
3.3.对于静态成员函数
声明静态成员函数指针: *函数指针变量名
获取类成员函数地址: &类名::成员函数名
因为静态成员是跟着类走的,所以在类里相当于是全局的,所以不用再用类名::来限定作用域
void (* myfpointstatic)(int) = &CT::staticfunc; //定义一个静态的类成员函数指针并给初值
myfpointstatic(100); //直接使用静态成员函数指针名即可调用静态成员函数
4.类成员变量指针
4.1.对于普通成员变量
public:
int m_a;
在main主函数中
int CT::*mp = &CT::m_a;
跟踪调试发现这个指针并不是真正意义的指针,他不是指向内存的地址,而是这个成员变量和该类对象首地址之间的偏移量
4.2.对于静态成员变量
则是一个真正的地址,当然也不用加CT这个类作用域
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)