1、explicit关键字
class A
{
public:
/*A(int a)
:_a(a)
{}*/
explicit A(int a)
:_a(a)
{}
private:
int _a;
};
int main()
{
A a1(1);
A a2 = 3;
system("pause");
return 0;
}
当构造函数加explicit关键字后,A a2 = 3就会报错;正常情况下A a2 = 3的过程是编译器用3构造一个无名对象,在将这个对象的值给a2,编译器后台优化了这个过程,所以只调用了构造函数;
explicit 修饰构造函数,就禁止了单参构造函数的隐式转换。
2、static成员
概念
声明成static的类成员被称为类的静态成员,当类的成员变量被static修饰后,该成员变量就只能在类外初始化;当类的成员函数被static修饰后,称为静态成员函数。
特性
1、静态成员变量必须类外初始化。
2、静态成员函数没有this指针,不能访问非静态成员。
3、静态成员为所有类对象所共享。
4、类的静态成员可以用类域限定符 :: 访问,也可以用类对象 . 静态成员访问。
5、静态成员同样也受3种访问限定符限制,同样具有返回值。
6、静态成员函数不能调用非静态成员函数,非静态成员函数可以调用静态成员函数。
3、友元
友元函数
友元函数是可以直接访问类所有成员的非成员函数,它的定义在类外,不属于任何类;使用的时候在类内声明即可,声明位置不受访问限定符限制,声明在任何位置都可以。
class A
{
//声明友元类
friend void Print(const A& k);
public:
A(int a)
:_a(a)
{}
private:
int _a;
};
void Print(const A& k)
{
cout << k._a << endl;
}
int main()
{
A a1(1);
Print(a1);
return 0;
}
注意:
1、友元函数可以访问类的成员函数,但不是类的成员函数。
2、友元函数不能被const修饰,可以声明为static静态函数。
3、友元函数声明位置不受访问限定符限制。
4、一个函数可以是多个类的友元函数,在类中声明即可。
5、友元函数调用与普通函数一样。
友元类
友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的所有成员。
友元关系是单向的,假设B是A的友元,B可以访问A的所有信息,但是A无法访问B的信息。
友元关系不具备交换性,学了继承以后,当父类有一个友元,子类不会继承这个友元关系。
友元关系不能传递,假设B是A的友元,C是B的友元,不能说明C是A的友元。
class A
{
friend class B;
};
class B
{};
4、内部类
概念
当类B定义在类A的内部,类B就叫做内部类。此时类B是一个独立的类,不属于外部类;外部类对内部类没有访问权限,而内部类是外部类的友元,内部类可以通过外部类的对象来访问外部类种所有成员。
class A
{
public:
class B
{
public:
//用外部类对象作为参数
void func(const A& a)
{
//可以直接访问外部类的静态成员变量
cout << k << endl;
//通过外部类对象访问外部类成员变量
cout << a.h << endl;
}
};
private:
static int k;
int h;
};
//静态成员变量类外初始化
int A::k = 1;
int main()
{
//B b1;//不能直接创建内部类对象
//必须指明内部类B在外部类A中
//再创建内部类对象
A::B b2;
A a1;
//通过传一个A类对象调用内部类函数func()
b2.func(a1);
return 0;
}
特性
1. 内部类可以定义在外部类的public、protected、private都是可以的。
2. 内部类可以直接访问外部类中的static、枚举成员,不需要外部类的对象/类名。
3. 外部类的大小和内部类没有关系,不要将内部类也计算到外部类中。