类和对象(下)(一)

简介: 类和对象(下)(一)

初始化列表

初始化列表是构造函数的一种方式,使用初始化列表可以解决一些构造函数体赋值难以解决的问题

首先先再次认识一下构造函数

构造函数

1.构造函数体赋值

构造函数体赋值就是,我们先前最为常用的方法

class Date {
public:
  Date(int year, int month, int day)//只是在函数体中赋值
  {
    _year = year;
    _month = month;  //{} 这是函数体
    _day = day;
  }
private:
  int _year;
  int _month;
  int _day;
};
int main()
{
  Date d(2023, 5, 12);//我们要知道的是,调用构造函数之后,对象d有了一个初始值,但是不能成为对对象成员变量的初始化,构造函数体中的语句只能将其称为赋初值,而不能称作初始化。因为初始化只能初始化一次,而构造函数体内可以多次赋值。
  return 0;
}

2.初始化列表

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

class Date {
public:
  Date(int year, int month, int day)
    :_year(year)
    , _month(month)
    , _day(day)
  {}
private:
  int _year;
  int _month;
  int _day;
};
int main()
{
  Date d(2023, 5, 12);
  return 0;
}

注意

1.每一个成员变量在初始化列表中只能出现一次(初始化只能初始化一次)

2.构造函数体赋值,使得对象进行了赋初值,但是不能成为初始化(初始化只能一次,但是函数体里面可以多次赋值)

3. 类中包含以下成员,必须放在初始化列表位置进行初始化:

1.引用成员变量

2.const成员变量

3.自定义类型成员(没有默认构造函数时)

对于上述三种类型,我们只能使用初始化列表来进行初始化

class Date {
public:
  Date(int year, int month, int day)
    :_year(year)
    , _month(month)
    , _day(day)
    ,a(year)
    ,b(year)
    ,c(year)
  {}
private:
  int _year;
  int _month;
  int _day;
  int& a;
  const int b;
  B c;
};
class B {
public:
  B(int data) {
    _data = data;
  }
private:
  int _data;
};
int main()
{
  Date d(2023, 5, 12);
  return 0;
}

对于引用类型,和const类型成员变量,共同特点是只能初始化一次,所以不能放在构造函数体中,只能使用初始化列表来初始化变量

对于自定义类型成员(无默认构造),是因为,当有默认构造的时候,编译器会自动调用自定义类型的默认构造,但是当我们重载构造函数之后,就需要我们手动对于自定义类型进行初始化,(也是只能一次)所以只能在列表中初始化

总之,在这以后,我们尽量多去使用初始化列表来进行初始化,因为初始化列表好比是构造函数体初始化的Plus版本,对于一般类型都能进行初始化,而且可以对于引用类型,const类型、自定义类型都能进行初始化(构造函数体不能实现)

成员变量在类中声明的次序就是其在初始化列表中的初始化次序,与其在初始化列表中的先后次序无关

所以以后写初始化列表的时候,列表顺序保持和声明顺序一致

explicit关键字

在使用构造函数实例化对象的时候,是可以可以通过隐式转换来实例化的

构造函数对于单个参数或者是出去第一个参数无默认值其余均有默认值的构造哈桑怒胡,可以有类型转换的作用(隐式转换)

//隐式转换
class Date {
public:
  //Date(int date)
  //{
  //  _date = date;
  //}
  void Print()
  {
    cout << _date <<" " <<_a<<" " <<_b<< endl;
  }
  Date(int date,int a = 2,int b = 3)
    :_date(date)
    ,_a(a)
    ,_b(b)
  {}
private:
  int _date;
  int _a;
  int _b;
};
int main()
{
  Date d1(1);//这一种是我们常用的实例化对象的方式
  Date d2 = 1;//这个就是涉及到隐式转换   将int类型转换成Date类型,又因为是构造函数是单个参数
  d1.Print();
  d2.Print();
  return 0;
}

这一种隐式转换,是对于自定义类型的隐式转换,内置类型的隐式转换在C语言中已经讲解了,所以我们只需要知道自定义类型隐式转换的条件即可

自定义类型隐式转换流程

将内置类型,如本文的int类型转换成Date类型,调用Date构造函数,创建一个临时对象,然后再去调用拷贝构造函数去赋值给d2,按理说,我们应该知道的是,隐式转换是在一条语句中连续两次调用构造函数

class Date {
public:
  //Date(int date)
  //{
  //  _date = date;
  //}
  void Print()
  {
    cout << _date << " " << _a << " " << _b << endl;
  }
  Date(int date, int a = 2, int b = 3)
    :_date(date)
    , _a(a)
    , _b(b)
  {
    cout << "构造函数" << endl;
  }
  Date(const Date& d) {
    cout << "拷贝构造函数" << endl;
  }
private:
  int _date;
  int _a;
  int _b;
};
int main()
{
  Date d1(1);//这一种是我们常用的实例化对象的方式
  Date d2 = 1;//这个就是涉及到隐式转换   将int类型转换成Date类型,又因为是构造函数是单个参数
  d1.Print();
  d2.Print();
  return 0;
}

对于上述的隐式转换,如果我们不需要这样,避免自定义类型隐式转换,那就使用关键字explicit

使用explicit关键字修饰函数,即可禁止类型转换

class Date{
public:
    explicit Date(int year)  //explicit关键字修饰,禁止隐式类型转换
        :_year(year)
        {}
private:
  int _year;   
};
int main()
{}

隐式类型转换,可读性就不是很好了,所以使用explicit禁止类型转换

static成员

static修饰的成员称为类的静态成员,有静态成员变量or静态成员函数。静态成员变量一定要在类外进行初始化

我们知道自定义类型的初始化方式,使用构造函数的话有两种,第一个是构造函数体初始化,第二个是初始化列表,但是明显不能解决这个static的初始化,因为static修饰的成员变量的生命周期是整个程序

所以解决方法为,使用全局域对于静态变量进行初始化

class Date
{
public:
    Date(int year)
        :_year(year)
    {}
    static int get_a()  我们不实例化对象,所以就直接用static修饰,类名调用
    {
        return _a;
    }
private:
    int _year;
    static int _a;//public修饰的静态函数/静态变量是可以通过类名直接访问的,但是如果是private的话,是需要类中的函数来访问,所以我们应该定义返回函数
};
int Date::_a = 0;
int main()
{
    cout <<Date::get_a() << endl;
    return 0;
}

对于静态static关键字,主要就下面几个方面的细节要注意

1.static修饰的变量声明周期是整个程序,如果是类中的成员变量被static修饰,那么需要在类外进行初始化,因为类中构造函数不能满足需求,且类外(全局域)初始化就一次,放在静态区,对象使用的时候可以直接调用(只是声明周期不一样而已)

2.static修饰的成员变量or成员函数,是可以直接使用类名来调用的

3.访问限定符private修饰的static成员变量,可以通过成员函数来访问,返回

class Date{
public:
   static int Print()  { cout<<a<<endl;}
private:
   static int a;
};
int Date::a=0;//类外初始化赋值static变量
int main()
{
   cout<<Date::Print()<<endl;
   return 0;
}

总结

  1. 静态成员所有类对象所共享,不属于某个具体的对象,存放在静态区
  2. 静态成员变量必须在类外定义定义时不添加static关键字,类中只是声明
  3. 类静态成员即可用 **类名::静态成员 或者 对象.静态成员 **来访问
  4. 静态成员函数没有隐藏的this指针,不能访问任何非静态成员
  5. 静态成员也是类的成员,受public、protected、private 访问限定符的限制

注意:静态成员函数可以调用静态成员函数,但是不能调用非静态函数,非静态函数两者都能调用

这是因为,static修饰的类方法,是整个类所共有的,不属于任何一个对象,所以就没有this指针(形参中没有this指针),继而无法调用非static修饰的函数(this指针是用来接收当前对象的地址的)

函数都存放在代码段

相关文章
|
SQL 监控 Oracle
Oracle 数据库发生等待事件:enq: TX - row lock contention ,排查思路
Oracle 数据库发生等待事件:enq: TX - row lock contention ,排查思路
Oracle 数据库发生等待事件:enq: TX - row lock contention ,排查思路
|
1月前
|
存储 人工智能 编解码
AI短剧/AI广告生成实战流程:阿里云百炼新上线的HappyHorse 1.1功能详解、参数调试、成本指南
HappyHorse是阿里云推出的端到端AI视频生成大模型,2026年6月22日正式上线迭代版本HappyHorse 1.1,部署在阿里云百炼平台对外开放API调用与在线调试能力,主打短剧、电商广告、品牌宣传片、内容营销短片四大商用内容场景。相比初代HappyHorse 1.0,新版本在动态时序、角色一致性、画面质感、音画协同、长指令理解五大核心维度完成系统性升级,解决旧版动作僵硬、人物面部失真、多角色画面互相污染、长分镜逻辑断裂等行业常见痛点。
454 2
|
2月前
|
数据采集 Web App开发 JavaScript
Python 爬虫动态 JS 渲染与无头浏览器实战选型指南
Python 爬虫动态 JS 渲染与无头浏览器实战选型指南
|
2月前
|
弹性计算 人工智能 运维
阿里云服务器2核2G怎么选择?轻量应用服务器38元与云服务器99元区别及选购策略参考
2026年阿里云两款热门2核2G入门级云服务器,轻量应用服务器38元/年,峰值200M带宽、40G ESSD云盘,预装OpenClaw等镜像,适合新用户快速部署AI应用,但仅限新用户抢购且续费价格高。云服务器ECS经济型e实例99元/年,固定3M带宽不限流量,新老用户同享且续费同价至2027年3月,适合长期稳定运营。追求极致首年性价比和快速上云选轻量,注重长期稳定和环境自定义选ECS,助力个人开发者与中小企业低门槛上云。
|
2月前
|
人工智能 开发工具 git
Zed 这个 Git 小功能,让我少敲了 1000 次复制粘贴
Zed 新增 `git: view commit` 命令,支持在命令面板中直接输入任意 Git ref(如 `HEAD`、`main`、`abc1234` 或 `HEAD~3`),秒开提交详情。带实时预览、防抖查询与友好报错,免去复制粘贴,大幅提升高频操作效率。(239字)
164 1
|
Kubernetes 数据可视化 容器
『Kubernetes』在k8s中部署Dashboard可视化面板
📣读完这篇文章里你能收获到 - 保姆级的K8S安装Dashboard - 可视化管理Kubernetes
2285 1
『Kubernetes』在k8s中部署Dashboard可视化面板
|
4月前
|
弹性计算 人工智能 JavaScript
阿里云+本地全平台部署OpenClaw(Clawdbot)|千问/Coding Plan API配置+避坑+常见问题全解
2026年,OpenClaw(原Clawdbot)凭借轻量化架构、全平台兼容与强大的大模型集成能力,成为搭建个人/企业级AI智能体的首选框架。阿里云提供官方认证的一键部署方案,支持轻量应用服务器、ECS云服务器等多种形态,实现云端稳定运行;本地则完美适配MacOS、Linux、Windows11三大系统,满足隐私部署与本地调试需求。阿里云千问大模型凭借本土化优势与稳定性能,是OpenClaw的首选模型;而阿里云百炼Coding Plan提供免费额度,成为零成本入门的优质选择。
651 0
|
4月前
|
传感器 运维 监控
运维那些事儿(7):机房动环监控与预警,守住运维第一道防线
运维核心是“防患于未然”,机房动环监控正是第一道防线。本文剖析温湿度、电源、空调、安全四大监控场景及关键指标,揭秘真实故障案例
运维那些事儿(7):机房动环监控与预警,守住运维第一道防线
|
6月前
|
数据采集 人工智能 API
小红书笔记详情API在竞品分析中的应用实践
小红书笔记详情 API 是合规竞品分析的核心工具,其价值在于能获取标准化的笔记内容、互动数据、作者画像等信息,帮助品牌 / 开发者快速洞察竞品的内容策略、用户偏好、爆款逻辑。需要强调的是:仅可在获得官方授权或针对公开合规数据的前提下使用,严禁未经许可批量爬取或滥用数据。
|
7月前
|
数据采集 人工智能 监控
大型企业怎么做数据治理?(2025年12月更新)
瓴羊Dataphin是阿里云旗下一站式智能数据构建与管理平台,助力大型企业破解数据孤岛、标准不一、质量参差等治理难题。依托全链路智能化能力,支持50+异构数据源接入,实现数据采集、建模、治理、服务闭环。通过标准化建模、元数据管理、质量监控与血缘追踪,保障数据可信可控;以主题式服务赋能业务人员自助分析,推动数据价值落地。广泛应用于零售、餐饮、地产、制造、金融等行业,支撑会员运营、供应链优化、风险控制等场景。提供全托管服务与灵活部署方案,助力企业高效构建数据中台,释放数据要素价值。

热门文章

最新文章