本篇主要是填补前两篇类和对象中的小知识点
第一篇:C++--类和对象(一)-CSDN博客
第二篇:C++--类和对象(二)-CSDN博客
目录
1.初始化列表
2.友元(friend)
3.内部类
1.初始化列表
在之前实现构造函数的时候,我都是在函数体内对成员变量初始化,但构造函数还有一种初始化方式,就是初始化列表,初始化列表的使用方式是以一个冒号开始,通过逗号分隔数据,每一个成员变量的后跟着一个括号里面放初始值或表达式
1.每个成员变量在初始化列表中只能出现一次,初始化列表可以认为式每个成员变量定义初始化的地方
2.引用成员变量,const成员变量,和没有默认构造的类类型变量(需要进行传参),必须在初始化列表上进行初始化,否则编译报错
3.C++11支持在成员声明的地方给缺省值,这个缺省值主要是给没有显示在初始化列表中的成员使用的。推荐对于引用成员变量,const成员变量,和没有默认构造的类类型变量在声明的地方写缺省值
4.尽量使用初始化列表初始化,因为不管怎么样,成员变量都会走初始化列表,如果在声明的地方写了缺省值,那么初始化列表时就会使用缺省值初始化,对于既没有在声明写缺省值也没有在初始化列表显示的成员,内置类型取决于编译器,它有可能不作为;自定义类型成员会调用这个成员类型的默认构造函数,没有那就报错
5.初始化列表中的成员变量按照类中声明的顺序一致,在初始化列表中的先后顺序不取决于列表中的顺序
class stack
{
public:
stack(int n = 4)
:_acc (new int[n])//当作malloc就行
, _top(0)
,_capacity(n)
{}
private:
int* _acc=nullptr; //缺省值
size_t _top=0;
size_t _capacity=0;
};
虽说尽量使用列表初始化,但还是要分情况,请自行判断是使用函数体好还是初始化列表好
2.友元(friend)
友元提供了一种突破类访问限定符封装的方式,友元分为友元函数和友元类,在函数声明或者类声明的前面加friend,并将友元声明放在一个类里面
1.友元修饰过的函数可以访问类的私有和保护成员,但它知识一个声明,他不是类的成员函数
2.友元函数可以在任意位置声明,它无视访问限定符
3.一个函数可以是多个类的友元函数
4.友元类中的成员函数都可以是另一个类的友元函数,都可以访问另一个类中的私有和保护成员
5.友元类是单向的,不具备交换性,如A类是B类的友元,但B类不是A类的友元
class A
{ //友元声明
friend class B; //将类B设为友元
public:
A(int y = 1)
{
_y = y;
}
private:
int _y;
};
class B
{
public:
B(int x = 0)
{
_x = x;
}
void print(const A& a) //B内可以访问A的私有成员
{
cout <<"A:" << a._y << endl;
cout << "B:" << _x << endl;
}
void print() //函数重载
{
cout << "B:" << _x<<endl;
}
private:
int _x;
};
int main()
{
B b;
A a;
b.print(a);
b.print();
return 0;
}
运行结果:
注意:友元能够突破访问限定的功能,这在一定程度上破坏了封装,所以少量使用
3.内部类
类也支持嵌套,可以将一个类定义在另外一个类的内部,而这种类就叫内部类。内部类是一个独立的类,和定义在全局相比,它只会受到外部类和访问限定符的限制,所以外部类定义的对象中不包含内部类
1.内部类自动是外部类的友元类
2.内部类也是封装的一种,假设A类和B类关系紧密,且想把A类作为B类的专属,那么就可以考虑将A类放到privat(私有)/protected(保护)位置,这样A类就是B类专属
注意:内部类的使用比较容易出错所以较少使用,如果关系并不密切那还不如使用友元
class C
{
private:
int _x = 0;
public:
class D
{
public:
void print(const C&c)
{
cout<<"内部类D;"<< c._x << endl;
cout<<"外部类C:" << _y << endl;
}
private:
int _y = 1;
};
};
int main()
{
C c;
C::D d;
d.print(c);
return 0;
}
本章主要是填补前几章的知识,希望本篇能够帮助到你,感谢你的阅读