第七课
1.explicit关键字
·C++提供了关键字explicit,禁止通过构造函数进行的隐式转换,声明为explicit的构造函数不能在隐式转换中使用、
·注意:explicit用于修饰构造函数,防止隐式转换,是针对单个参数的构造函数(或者除了第一个参数外其余参数外其余参数都有默认值的多参构造)而言;
事例:
class My
{
private:
char*m_name;
int m_age;
public:
explicit My(int age){};//无法隐式转换
My(const char* name){};
};
2,静态成员变量
所有对象都有的属性;
定义:
1,关键字static可以用于说明一个类的成员为静态成员,静态成员提供了一个同类对象的共享机制;
2,一个类中可以有一个或多个静态成员变量,所有的对象都共享这些静态成员变量,都可以引用它;
3,static成员变量和普通static变量一样,都在内存分区中的全局数据区分配内存,到程序结束时才释放,意味着,static成员变量不随对象的创建而分配内存,也不随对象的销毁而释放内存,而普通成员变量在对象创建时分配内存,在对象销毁时释放内存;
4,静态成员变量既可以通过对象名访问,也可以通过类名访问,但要遵循private、protected和public关键字的访问权限限制;
5,静态成员变量必须在类的内部声明,在类的外部定义。(C++17有新写法)
//C++17之前的写法:
class My
{
private:
static int m_size;//类的内部
};
int My::m_size=0;//类的外部
//C++17之后的写法:
class My
{
private:
inline static int m_size=999;//类的内部
};
3,静态成员函数
1,在类中,static除了可以声明静态成员变量,还可以声明静态成员函数,普通成员函数可以访问所有成员(静态和非静态都可以),静态成员函数只能访问静态成员;
2,调用方式:
·定义对象,通过对象去调用;
·不定义对象,直接通过类名去调用
class My
{
public:
static void size()
{
}
};
int main()
{
MY h;
h.size();//通过对象去调用;
My::size();//通过类名去调用
return 0;
}
5,编译器对普通成员函数的内部处理
1,C++类对象中的成员变量和成员函数是分开存储的;
·成员变量:
1,普通成员变量:存储于对象中,与struct变量有相同的内存布局和字节对齐方式;
2,静态成员变量:存储于全局数据区中;
·成员函数:存储于代码段中;
6,this指针属性
1,this是C++中的一个关键字,也是一个const指针,它指向当前对象,通过它可以访问当前对象的所有成员;
2,所谓当前对象,是指正在使用的对象;
事例:
t.getA():a;
//a就是当前对象,this就指向t;
3,this只能用在类的内部,通过this可以访问类的所有成员,包括private、protected、public属性;
//若类成员函数的形参和类的属性,名字相同,通过this指针解决
class My
{
public:
My(int age,char* name)
{
this->age=age;
this->name=new char[10];
strcpy(this->name,name);
}
private:
int age;
char* name;
};
7,const成员变量
1,类中的const成员初始化
class Text
{
public:
Text(int a):b(a){};//利用初始化列表初始化
const int b;
};
2,注意事项:
·必须使用初始化参数列表初始化;
·不可以修改const成员变量;
3,让普通成员无法在函数内修改(在最后面加上const)
事例:
class My
{
public:
int GetA() const//变成常成员函数
{
//id=6;//error
return id;
}
int id;
};
4,const对象只能访问const成员
例子:const My n;
8,友元函数
1,能够在类的外部访问非公有成员;
定义:
友元(friend)机制允许一个类对其非公有成员的访问权授予指定的函数或者类,友元的声明以friend开始,它只能出现在类定义的内部,友元声明可以出现在类中的任何地方:友元不是授予友元关系的那个类的成员,所以它们不受其声明出现部分的访问控制影响;
·友元函数是指某些虽然不是类成员函数却能够访问类的所有成员的函数,就像好朋友一样;
例子:
class A
{
public:
friend void SetData(int data,A&a);
private:
int data;
};
void SetData(int data,A&a)
{
a.data=data;
}
9,友元类
在类的内部定义其他类时,前面加上friend;
10,类的成员函数指针
1,定义类的成员函数指针
·返回值(类名::*指针名)(参数列表)
void (B :😗 p)(A);
2,赋值
·指针名=&类名::函数名
p=&B::Md;//初始化时必须取地址;
3,调用
·在类内调用
(this->*p)(A());//调用时必须要用对象去调用;
·在类外调用
B t;
B *py=new B;
(t .* p)(jj);
(py ->* p)(jj);