C++【初始化列表】【explicit】【匿名对象】【Static成员】【友元】【内部类】详解

目录

初始化列表

语法

特性

explicit

匿名对象

功能

语法

应用场景

Static成员

特性

友元

友元函数

友元类

内部类

特性


初始化列表

在构造函数中给成员函数赋值,并不是真正的初始化,因为初始化只有一次,而构造函数内可以对成员变量多次赋值。真正的初始化是在初始化列表中完成的。

语法

以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟
一个放在括号中的初始值或表达式。初始化列表可以和函数体混着用。
class Date
{
public :
        //初始化列表是每个成员定义的地方
Date ( int year , int month , int day )           
    : _year ( year )                                           
    , _month ( month )                             
    , _day ( day )                                     
    {}                                                    
                                                          
private :
        int _year = 1 ;        //每个成员的声明
        int _month = 1 ;
        int _day = 1 ;
   //C++支持缺省值,这个缺省值是给初始化列表的
   //如果初始化列表没有显示给值,就用这个缺省值
};

特性

1. 每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次)
2. 类中包含以下成员,必须放在初始化列表位置进行初始化:
* 引用成员变量
* const成员变量
* 自定义类型成员(且该类没有默认构造函数时)
class A
{
public :
        A ( int a )
        : _a ( a )
        {}
private :
        int _a ;
};
class B
{
public :
        B ( int a , int ref )
        : _aa ( a )
        , _ref ( ref )
        , _n ( 10 )
{}
private :
        A _aa ;   // 没有默认构造函数
        //必须定义时初始化
        int & _ref ;   // 引用
        const int _n ; // const
};
3. 初始化列表是每个成员定义的地方。 不管你写不写,每个成员都要走初始化列表。
* 自定义类型默认会调用构造函数是初始化列表调的这么理解是可以的。不在初始化列表中初始化自定义成员,也会在初始化列表中隐式调用构造函数进行初始化。所以尽量使用初始化列表初始化。
4.成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后
次序无关

explicit

构造函数不仅可以构造与初始化对象,对于单个参数或者除第一个参数无默认值其余均有默认值
的构造函数,还具有类型转换的作用
class A
{
pubilc:
        A (int i )
                :_a ( i )
        {}
private:
        int _a;
};
int main ()
{
        A aa1 (1);
        
        //单参数构造函数的隐式类型转换
        A aa2 = 2;      //用2调用A构造函数生成一个临时对象,再用这个对象去拷贝构造aa2
                             //新一点的编译器会再优化,优化成用2直接构造
        return 0;
}
C++11后,多参数的构造函数也支持类型转换,不过需要把参数放在{}内部传入
class A
{
public:
        B(int b1,int b2)
                :_b1(b1)
                ,_b2(b2)
        {}
private:
        int _b1;
        int _b2;
};
int main()
{
        B bb1 = {1,2};
        const B& ref = {2,2};
        return 0;
}
用explicit修饰构造函数,将会禁止构造函数的隐式转换

匿名对象

功能

创建一个没有名字的对象,生命周期只在这一行。

语法

类名(参数)

//有名对象。特点:生命周期在当前局部域

A aa1(1);

//匿名对象。特点:生命周期只有一行

A(2);

使用const引用可以延长匿名对象的生命周期

const A& x = A(1);//此时A(1)的生命周期与x一致。

应用场景

*访问某个函数或者变量,然后立即销毁

*做返回值

A func()

{

       return A(5);

}

Static成员

被static修饰的成员是静态成员,静态成员是所有对象共享的成员。

特性

静态成员必须在类外定义,定义时不加static关键字,只在声明时加;静态成员函数可在类内定义。

class A

{

public:

        static void func()

        {} 

private:

        static int a;

};

int A::a = 0;

类静态成员即可用 类名::静态成员 或者 对象.静态成员 来访问

静态成员函数没有隐藏的this指针,不能访问任何非静态成员

静态成员也是类的成员,受public、protected、private 访问限定符的限制

友元

友元分为:友元函数友元类

友元函数

友元函数可以直接访问类的私有成员,它是定义在类外部普通函数,不属于任何类,但需要在
类的内部声明,声明时需要加friend关键字
friend viod func();
特性
*友元函数可访问类的私有和保护成员,但不是类的成员函数
*友元函数不能用const修饰
*友元函数可以在类定义的任何地方声明,不受类访问限定符限制
*一个函数可以是多个类的友元函数
*友元函数的调用与普通函数的调用原理相同

友元类

语法

friend class Date;

特性

友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。
友元关系是单向的,不具有交换性。
友元关系不能传递
友元关系不能继承

内部类

如果一个类定义在另一个类的内部,这个内部类就叫做内部类。内部类就是外部类的友元类,但是外部类不是内部类的友元。

特性

1. 内部类可以定义在外部类的public、protected、private中。
2. 内部类可以直接访问外部类中的static成员,不需要外部类的对象/类名。
3. sizeof(外部类)=外部类,和内部类没有任何关系。
4.内部类可以访问外部类的私有
  • 30
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值