3.6 ·初始化列表·explicit·隐式类型转换·匿名对象·static·友元

本文详细介绍了C++中构造函数的使用方法,包括初始化列表、explicit关键字的作用、隐式类型转换、匿名对象的概念、static关键字的用法以及友元的相关知识点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、初始化列表:以一个冒号开始,接着以一个逗号分割的数据成员列表,每个“成员变量”后面跟一个放在括号中的初始值或表达式。如下格式:     

class Date
{
    public:
            Date (int year,int month,int day)
        {
                :_year(year)
                ,_month(month)
                ,_day(day)
        }
    private:
            int _year;
            int _month;
            int _day;
};

为什么要初始化列表呢?类中的有些成员变量必须借助初始化列表,有些变量借助初始化列表效果更好。如类中的引用成员变量、const 成员变量,由于他们只有一次初始化的机会,所以引用成员变量只能在定义的地方初始化,const成员变量必须在定义的地方初始化,而类中的自定义类型成员没有构造函数时,此时可借助初始化列表初始化自定义类型成员;如果有构造函数,在构造函数{}上面写自定义类型成员的初始化列表,则先会执行自定义类型成员的初始化列表,再执行构造函数{}内部的内容。建议能使用初始化列表就使用初始化列表初始化,使用初始化列表基本上没有什么问题,初始化列表的初始化顺序是按照申明的顺序来的,类中的内置类型的缺省实际上是给初始化列表的,初始化列表无法初始化类中的静态成员,初始化列表可以认为是类中成员变量定义的地方

二、explicit:修饰构造函数,禁止类型转换

explicit Date(int year)
        :_year(year)
{}
int main()
{
    Date d1(2022);//直接调用构造函数
    Date d2 = 2022;//构造+拷贝构造+优化=>直接调用构造.加了explicit后此句执行不通

构造+拷贝构造+优化=>直接调用构造 中的构造 指用2022构造一个Date(int year),再把这个构造拷贝给d2

三、隐式类型转换

int i = 10;
double d = i;//把int(i)->double(d)叫隐式类型转换,其实是把int转换成中间变量double,再把中间变量double转换成double,其中中间变量具有常属性,因此d 的double要用const修饰,最终为:const double d = i

四、匿名转换:生命周期只有一行

正常书写:Date d3(2022)
匿名对象:Date(2022)//生命周期只有一行。所谓匿名对象其实就是把类型定义的变量给隐藏起来了(或者认为没书写这个变量)

五、static

声明为static的类成员称为类的静态成员,用static修饰的类的成员变量称为类的静态成员变量,用static修饰的类的成员函数,称为类的静态成员函数,类的静态成员变量一定要在类外进行初始化。类的静态成员变量无法用初始化列表初始化,如private中的静态成员无法给缺省值,因为缺省值是给初始化列表的=>总结:

类的静态成员:static修饰的函数、static修饰的声明。它们都叫类的静态成员,类的静态成员由它俩组成

static修饰的函数 叫类的静态成员函数;
static修饰的声明 定义了一个变量叫 类的静态成员变量

class A
    {
        public:
            A() { ++_scount; }
            A(const A& t) { ++_scount; }
            ~A() { --_scount; }
            static int GetACount() { return _scount; }
        private:
            static int _scount;
    }; 
 
int A::_scount = 0;//类外面初始化

void TestA()
    {
            cout << A::GetACount() << endl;
            A a1, a2;
            A a3(a1);
            cout << A::GetACount() << endl;
    }

类的静态成员特征:

1)一个类如果定义了多个变量(如Date A,B,C),那么这个类的静态成员在这些变量中是共用的

2)类中的静态成员变量必须在类外定义,定义时不添加static关键字,类中只是声明

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

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

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

六、友元 :一种突破封装的方式,借助友元可以从类外访问类里面。友元有关的主要关注 友元函数,友元类,内部类。

友元函数:可以直接访问类的私有成员,他是定义在类的外部的普通函数,不属于任何类,但需要在类的内部声明,声明时需要加friend关键字。

说明:
友元函数可访问类的私有和保护成员,但不是类的成员函数;
友元函数不能用const修饰;
友元函数可以在类定义的任何地方声明,不受类访问限定符限制;
一个函数可以是多个类的友元函数;
友元函数的调用与普通函数的调用原理相同。

友元类:将一个类B变成另一个类A的友元(函数),这个类B的定义不在A里面

说明:
友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员;
友元关系是单向的,不具有交换性;
友元关系不能传递;(如,如果C是B的友元,B是A的友元,则不能说明C是A的友元。)
友元关系不能继承

内部类:如果一个类定义在另一个类的内部,这个内部类就叫做内部类。

说明:
内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去访问内部类的成员。外部类对内部类没有任         
  何优越的访问权限;
内部类就是外部类的友元类,内部类可以通过外部类的对象参数来访问外部类中的所有成员。但是外部类不是内部 
  类的友元;
内部类可以定义在外部类的public、protected、private都是可以的;
注意内部类可以直接访问外部类中的static成员,不需要外部类的对象/类名;
sizeof(外部类)=外部类,和内部类没有任何关系。


class A
{
public:
        class B
        {
        }
private:
}

B受A的类域限制,B定义变量前必须写A::,B也受A的访问限定符限制;
B天生是A的友元。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值