C++ 类和对象 构造函数(下)

news2024/11/22 21:36:55

一 初始化列表:

1.1 构造函数体赋值:

在C++中,构造函数用于创建对象并赋予其初始值。通常,我们可以在构造函数体内对成员变量进行赋值:

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

上述代码中,构造函数调用之后,对象的成员变量已经有了初始值,但是这种方法并不是真正的初始化,而是赋值。因为初始化只能进行一次,而构造函数体内可以多次赋值。

1.2 初始化列表:

初始化列表是一种在构造函数中初始化成员变量的方式,它在构造函数名之后,用一个冒号开始,接着是以逗号分隔的成员变量列表,每个成员变量后面跟一个放在括号中的初始值或表达式。

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成员变量的特征:

不可修改const成员变量一旦被初始化,就不能被修改。这意味着它们的值在对象的生命周期内是固定的。

必须初始化const成员变量必须在对象创建时被初始化,并且只能初始化一次。

代码示例:

使用初始化列表

class MyClass 
{
public:
    MyClass(int x)
        : _constMember(x) {}  // 使用初始化列表初始化const成员变量

private:
    const int _constMember;  // const成员变量
};

int main() 
{
    MyClass obj(10);
    return 0;
}

输出:

在构造函数体内赋值

class MyClass 
{
public:
    MyClass(int x)
    {
        _constMember = x;
    }

private:
    const int _constMember;  // const成员变量
};

int main() 
{
    MyClass obj(10);
    return 0;
}

输出:

为什么const修饰的成员变量只能初始化列表呢?

因为const修饰的成员变量只能在对象创建时直接初始化,这点初始化列表可以满足它 而构造函数体内赋值是默认初始化先给它一个随机值,但是const成员变量只接收一个确定的值,所以不行,那假如说默认初始化给的是确定的值那等结束完默认的初始化那构造函数也会传值过来,这不就进行二次赋值了吗,所以不管怎样都错了

引用成员变量:

我们先来说说引用成员变量的特征:

引用:引用是一个别名,用于引用另一个变量。引用在初始化之后不能再指向其他变量。

必须初始化:引用成员变量在对象创建时必须被初始化,并且只能初始化一次。

代码示例:

使用初始化列表

#include <iostream>
using namespace std;

class MyClass 
{
public:
    MyClass(int& ref)
        : _ref(ref) {}  // 使用初始化列表初始化引用成员变量

    void print() const 
{
        cout << "Reference value: " << _ref << endl;
}

private:
    int& _ref;  // 引用成员变量
};

int main() 
{
    int value = 10;
    MyClass obj(value);  // 通过初始化列表初始化引用成员变量
    obj.print();  // 输出: Reference value: 10

    return 0;
}

输出:

在构造函数体内赋值

#include <iostream>
using namespace std;

class MyClass {
public:
    MyClass(int& ref) {
        _ref = ref;  // 错误:无法在构造函数体内赋值
    }

private:
    int& _ref;  // 引用成员变量
};

int main() {
    int value = 10;
    MyClass obj(value);  // 编译器报错
    obj.print();

    return 0;
}

输出:

_ref = ref; 是错误的,因为 _ref 作为一个引用成员变量,必须在成员初始化列表中进行初始化,不能在构造函数体内重新赋值。

自定义类型成员(且该类没有默认构造函数时):

#include <iostream>
using namespace std;

class Complex {
public:
    Complex(double real, double imag)
        : _real(real), _imag(imag) {}  // 只有一个带参数的构造函数

    void print() const {
        cout << "Real: " << _real << ", Imag: " << _imag << endl;
    }

private:
    double _real;
    double _imag;
};

class MyClass {
public:
    MyClass(double real, double imag, int a, int b)
        :_a(a),  _complex(real, imag),_b(b) {}  // 使用初始化列表初始化所有成员变量

    void print() const {
        _complex.print();
        cout << "_a: " << _a << ", _b: " << _b << endl;
    }

private:
    Complex _complex;  // 自定义类型成员变量
    int _a = 0;  // 缺省值
    int _b = 1;  // 缺省值
};

int main() {
    MyClass obj(3.0, 4.0, 10, 20);  // 定义对象并初始化成员变量
    obj.print();

    return 0;
}

输出:

我们来说说它的执行顺序,顺便来复习复习前面学的知识:

首先为 MyClass 对象的成员变量 _complex_a_b 分配内存,然后再按照成员变量在 MyClass 类中声明的顺序进行初始化,先是 _complex,然后是 _a_b,调用 Complex 类的构造函数 Complex(real, imag),在其中为 Complex 对象的成员变量 _real_imag 分配内存并进行初始化,初始化 _a 为 10(通过初始化列表),初始化 _b 为 20(通过初始化列表)。

1.3 初始化与赋值的区别:

在C++中,初始化和赋值是两个不同的概念。初始化是指在对象创建时设置成员变量的初始值,而赋值是指在对象创建之后给成员变量赋予新的值。初始化只能进行一次,而赋值可以多次进行。

初始化

初始化是在对象创建时直接设置成员变量的初始值。例如,通过构造函数的初始化列表进行初始化:

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 s(2005, 4 , 26);
    return 0;
}

初始化列表:成员变量在对象创建时直接初始化,没有中间步骤。对于 const 成员变量、引用成员变量以及没有默认构造函数的类类型成员变量,这种方式是唯一的选择。初始化列表的效率更高,因为它避免了先默认初始化然后再赋值的过程。

赋值

赋值是在对象已经创建之后,给成员变量赋予新的值。例如,在构造函数体内进行赋值操作:

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 s(3354, 4 , 6);
    return 0;
}

构造函数体内赋值:成员变量先进行默认初始化,然后在构造函数体内进行赋值。这意味着在进入构造函数体之前,成员变量已经存在了一个初始值(通常是未定义的),然后再赋予新的值。这种方式对于某些类型(如 const 成员变量和引用成员变量)是不可行的,因为这些类型必须在初始化时赋值,而不能通过赋值操作来修改。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1937605.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

常见的数据分析用例 —— 信用卡交易欺诈检测

文章目录 引言数据集分析1. 读入数据并快速浏览2.计算欺诈交易占数据集中交易总数的百分比3. 类别不平衡对模型的影响3.1 总体思路&#xff08;1&#xff09;数据的划分&#xff08;2&#xff09;训练模型&#xff08;3&#xff09;测试模型&#xff08;4&#xff09;解决不平衡…

知迪科技发布了全新软件产品

近日&#xff0c;知迪科技发布了全新软件产品——Vehicle Bus Tool-Trace Version免费版。该软件产品能高效的离线分析汽车总线数据&#xff0c;并拥有一大亮点功能&#xff1a;Ethernet通信离线文件基于ARXML文件的信号级解析&#xff0c;具体操作如下&#xff1a; 1、新建一…

git修改提交姓名

git config --global user.name “新用户名” git config --global user.email “新邮箱地址” 修改提交的用户名 git config --global user.name “yu***”

java转义文本中的HTML字符为安全的字

java转义文本中的HTML字符为安全的字 &#xff0c;以下字符被转义&#xff1a;替换为 (&apos; doesnt work in HTML4) " 替换为 &quot; & 替换为 &amp; < 替换为 < > 替换为 >1.先添加hutool依赖到pom <dependency><groupId>cn…

Docker安装笔记

1. Mac安装Docker 1.1 Docker安装包下载 1.1.1 阿里云 对于10.10.3以下的用户 推荐使用 对于10.10.3以上的用户 推荐使用 1.1.2 官网下载 系统和芯片选择适合自己的安装包 1.2 镜像加速 【推荐】阿里镜像 登陆后&#xff0c;左侧菜单选中镜像加速器就可以看到你的专属地…

阿尔泰科技利用485模块搭建自动灌溉系统实现远程控制

自动灌溉系统又叫土壤墒情监控系统&#xff0c;土壤墒情监控系统主要实现固定站无人值守情况下的土壤墒情数据的自动采集和无线传输&#xff0c;数据在监控中心自动接收入库&#xff1b;可以实现24小时连续在线监控并将监控数据通过有线、无线等传输方式实时传输到监控中心生成…

怎样在 PostgreSQL 中实现数据的异地备份?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01;&#x1f4da;领书&#xff1a;PostgreSQL 入门到精通.pdf 文章目录 怎样在 PostgreSQL 中实现数据的异地备份&#xff1f;一、异地备份的重要性二、PostgreSQL 中的备份方…

Docker的安装【虚拟机】

Docker的安装【虚拟机】 准备环节【可跳过】 # 进入yum.repos.d目录&#xff0c;保留base.repo 和 CentOs-Base.repo&#xff0c;其余删除 cd /etc/yum.repos.d/ ----------------------------------------------------- # 现将base.repo 和 CentOs-Base.repo 存放至bak包中 …

SQL执行流程、SQL执行计划、SQL优化

select查询语句 select查询语句中join连接是如何工作的&#xff1f; 1、INNER JOIN 返回两个表中的匹配行。 2、LEFT JOIN 返回左表中的所有记录以及右表中的匹配记录。 3、RIGHT JOIN 返回右表中的所有记录以及左表中的匹配记录。 4、FULL OUTER JOIN 返回左侧或右侧表中有匹…

深度洞察市场需求,Vatee万腾平台定制化解决方案引领潮流

在当今这个日新月异的商业环境中&#xff0c;深刻理解并精准把握市场需求&#xff0c;已成为企业生存与发展的核心要义。Vatee万腾平台&#xff0c;作为行业内的佼佼者&#xff0c;凭借其卓越的定制化解决方案能力&#xff0c;正引领着市场潮流&#xff0c;为企业客户量身打造数…

【BUG】已解决:AttributeError: ‘DataFrame‘ object has no attribute ‘append‘

已解决&#xff1a;AttributeError: ‘DataFrame‘ object has no attribute ‘append‘ 目录 已解决&#xff1a;AttributeError: ‘DataFrame‘ object has no attribute ‘append‘ 【常见模块错误】 错误原因&#xff1a; 解决办法&#xff1a; 欢迎来到英杰社区https:/…

Linux—KVM虚拟化中(虚拟机克隆,快照,还原,删除)等应用实例

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f427;Linux基础知识(初学)&#xff1a;点击&#xff01; &#x1f427;Linux高级管理防护和群集专栏&#xff1a;点击&#xff01; &#x1f510;Linux中firewalld防火墙&#xff1a;点击&#xff01; ⏰️创作…

【数据结构初阶】顺序表三道经典算法题(详解+图例)

Hello&#xff01;很高兴又见到你了~~~ 看看今天要学点什么来充实大脑吧—— 目录 1、移除元素 【思路图解】 【总结】 2、删除有序数组中的重复项 【思路图解】 【总结】 3、合并两个有序数组 【思路图解】 【总结】 至此结束&#xff0c;Show Time&#xff01; 1、…

加拿大上市药品查询-加拿大药品数据库

在加拿大&#xff0c;药品的安全性、有效性和质量是受到严格监管的。根据《食品药品法案》的规定&#xff0c;所有药品制造商必须提供充分的科学证据&#xff0c;证明其产品的安全性和有效性。为此&#xff0c;加拿大卫生部建立了一个全面的药品数据库 &#xff08;DPD) &#…

Websocket自动消息回复服务端工具

点击下载《Websocket自动消息回复服务端工具》 1. 前言 在进行Websocket开发时&#xff0c;前端小伙伴通常是和后端开发人员同步进行项目开发&#xff0c;经常会遇到后端开发人员接口还没开发完&#xff0c;也没有可以调试的环境&#xff0c;只能按照接口文档进行“脑回路开发…

深入探究理解大型语言模型参数和内存需求

概述 大型语言模型 取得了显著进步。GPT-4、谷歌的 Gemini 和 Claude 3 等模型在功能和应用方面树立了新标准。这些模型不仅增强了文本生成和翻译&#xff0c;还在多模态处理方面开辟了新天地&#xff0c;将文本、图像、音频和视频输入结合起来&#xff0c;提供更全面的 AI 解…

昇思25天学习打卡营第20天|Diffusion扩散模型

Mindspore框架利用扩散模型DDPM生成高分辨率图像&#xff08;生成高保真图像项目实践&#xff09; Mindspore框架利用扩散模型DDPM生成高分辨率图像|&#xff08;一&#xff09;关于denoising diffusion probabilistic model &#xff08;DDPM&#xff09;模型Mindspore框架利…

GitHub CLI 发布 2.53.0

gh 是 GitHub 官方的命令行客户端工具&#xff0c;在此推荐给每一位在参与、想参与到 GitHub 上开源项目的小伙伴。体验异常舒适&#xff01; 常用的命令包括有&#xff1a; 登陆认证 gh auth login克隆代码仓库 gh repo clone linuxsuren/api-testing创建 Fork 仓库 gh repo f…

Java面试八股之Redis Stream的实现原理及应用场景

Redis Stream的实现原理及应用场景 Redis Stream是一种在Redis 5.0版本中引入的数据结构&#xff0c;它主要用于实现高效的消息队列服务。下面我将详细解释其实现原理以及一些常见的应用场景。 实现原理 1. 结构组成&#xff1a; - Redis Stream由一个或多个消息组成&#xf…

《无所不能的JavaScript · 异步编程》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…