当前位置: 首页 > article >正文

【C++】类的构造函数

类的构造函数

  • 1. 作用:
  • 2.语法规则:
      • 示例代码:构造函数语法
    • 2.1 特点:
      • 示例代码:自定义了构造函数,系统不会再生成默认构造函数
      • 示例代码:构造函数重载
  • 3.构造函数常见的写法
    • 3.1 无参构造函数
    • 3.2 带参数的构造函数
    • 3.3 带默认参数的构造函数
      • 示例代码:带默认参数的构造函数
      • 示例代码:带默认参数的构造函数写在类的外面
    • 3.4 带参数列表的构造函数
      • 示例代码:带参数列表的构造函数
    • 3.5 指定父类的构造函数
      • 示例代码:子类指定父类的构造函数
  • 4.构造函数的调用

1. 作用:

只要新建对象,类的构造函数都会被自动调用(对象不能主动调用构造函数)
构造函数专门用来新建对象的
实际应用:用来初始化对象

2.语法规则:

类名(形参列表)
{
代码
}

示例代码:构造函数语法

#include <iostream>using namespace std;class Animal
{
public:// 定义动物的构造函数Animal(){cout<<"动物的构造函数"<<endl;}private:/* data */};int main(int argc, char const *argv[])
{//创建三个对象//创建几个对象,构造函数就自动调用几次Animal a1, a2, a3;//错误的:对象不可以自己来调用构造函数 error: invalid use of ‘Animal::Animal’// a1.Animal();return 0;
}/*
执行结果:动物的构造函数动物的构造函数动物的构造函数
*/

2.1 特点:

  • 构造函数的名字必须跟类名相同
  • 构造函数没有返回值类型
  • 如果程序员没有定义构造函数,系统会自动生成一个无参的构造函数

默认构造函数:
Animal()
{
什么事情都不做,只创建对象,分配空间
}

如果程序员自定义构造函数(无论是否带参数),那么系统就不会再自动生成默认的构造函数

示例代码:自定义了构造函数,系统不会再生成默认构造函数

#include <iostream>using namespace std;/*构造函数用途:用来初始化对象里的数据如果程序员自定义构造函数(无论是否带参数),那么系统就不会再自动生成默认的构造函数
*/class Animal
{
public:// 通过Animal的构造函数对Animal的属性设置Animal(int _age){age = _age;cout<<"动物的带参数构造函数被调用了"<<endl;cout<<"age:"<<age<<endl;}private:int age;
};int main(int argc, char const *argv[])
{//正确,创建Animal的对象Animal a1(5);// 错误的,程序员写了带参数的构造函数,因此系统不会再生成无参构造函数,若要排除该错误,需自定义一个无参构造// 编译错误信息--》error: no matching function for call to ‘Animal::Animal()’Animal a2; return 0;
}/*
执行结果:动物的带参数构造函数被调用了age:5
*/
  • 构造函数可以重载,重载构造函数是为了实现创建对象的多样化

示例代码:构造函数重载

#include <iostream>using namespace std;/*构造函数可以重载,重载构造函数是为了实现创建对象的多样化
*/class Animal
{
public:// 通过Animal的构造函数对Animal的属性设置Animal(int _age){age = _age;cout<<"Animal(int _age)构造函数被调用了"<<endl;// cout<<"age:"<<age<<endl;}Animal(){cout<<"Animal()构造函数被调用了"<<endl;}Animal(string name){cout<<"Animal(string name)构造函数被调用了"<<endl;}Animal(int _age, string name){cout<<"Animal(int _age, string name)构造函数被调用了"<<endl;}
private:int age;
};int main(int argc, char const *argv[])
{//创建Animal的对象Animal a1(5);Animal a2;Animal a3("you");Animal a4(18, "you");return 0;
}/*
执行结果:Animal(int _age)构造函数被调用了Animal()构造函数被调用了Animal(string name)构造函数被调用了Animal(int _age, string name)构造函数被调用了
*/

3.构造函数常见的写法

3.1 无参构造函数

Animal()

3.2 带参数的构造函数

\quad 参数的类型以及个数没有任何限制,只要是合法的参数类型都可以作为构造函数的形参

3.3 带默认参数的构造函数

注意:这种版本的构造函数容易跟其它版本的构造函数起冲突(参数可以传递也可以不传递,就会跟无参构造或者其他版本的有歧义)

示例代码:带默认参数的构造函数

#include <iostream>using namespace std;/*带默认参数的构造函数
*/class Cat
{
public://天下无敌的版本Cat(string _name="旺财",int _age=0){name=_name;age=_age;cout<<"猫的构造函数带默认参数被调用了"<<endl;}void show(){cout<<"姓名: "<<name<<endl;cout<<"年龄: "<<age<<endl;}private:int age;string name;
};int main(int argc,char **argv)
{//创建猫的对象Cat c2;Cat c3("阿福");Cat c4("阿黄",5);c2.show();c3.show();c4.show();return 0;   
}/*
执行结果:猫的构造函数带默认参数被调用了猫的构造函数带默认参数被调用了猫的构造函数带默认参数被调用了姓名: 旺财年龄: 0姓名: 阿福年龄: 0姓名: 阿黄年龄: 5
*/

这种版本的构造函数如果定义在类的外面,默认参数不需要写

class Cat
{
public:Cat(int _age=5);};
Cat::Cat(int _age) //定义在类的外面不需要写默认参数
{}

示例代码:带默认参数的构造函数写在类的外面

#include <iostream>
#include <cstring>
using namespace std;/*带默认参数的构造函数写在类的外面
*/class Cat
{
public:// 默认参数写在声明处Cat(string _name="旺财",int _age=0);void show(){cout<<"姓名: "<<name<<endl;cout<<"年龄: "<<age<<endl;}private:int age;string name;
};Cat::Cat(string _name,int _age) //默认参数在类的外面不能写
{name=_name;age=_age;cout<<"猫的构造函数带默认参数被调用了"<<endl;
}int main(int argc,char **argv)
{//创建猫的对象Cat c2;Cat c3("阿福");Cat c4("阿黄",5);c2.show();c3.show();c4.show();return 0;    
}

3.4 带参数列表的构造函数

注意:这种版本的构造函数如果定义在类的外面,需要这么写

class Animal
{
public:Animal(int _age); //声明的时候不要写成参数列表
private:int age;其他类 对象obj;
};Animal::Animal(int _age):age(_age) //定义的时候写成参数列表
{cout<<"构造函数"<<endl;
}

示例代码:带参数列表的构造函数

#include <iostream>
#include <cstring>
using namespace std;/*带参数列表的构造函数
*/class Cat
{
public:Cat(string _name,int _age):name(_name),age(_age)  //name=_name  age=_age//带默认参数和参数列表形式混合//Cat(string _name="旺财",int _age=0):name(_name),age(_age){cout<<"带参数列表的构造函数"<<endl;}void show(){cout<<"姓名: "<<name<<endl;cout<<"年龄: "<<age<<endl;}private:int age;string name;
};int main(int argc,char **argv)
{//创建猫的对象Cat c1("阿黄",5);c1.show();return 0;    
}

3.5 指定父类的构造函数

\quad 子类指定父类的构造函数(如果不指定,默认情况下编译器总是调用父类的无参构造)

子类构造(形参列表):父类构造(传递给父类的实参)
{
}

示例代码:子类指定父类的构造函数

#include <iostream>
#include <cstring>
using namespace std;/*默认情况下:创建子类,都是调用父类的无参构造程序员想要指定调用父类的某个版本的构造,该如何实现?*/
class Animal
{
public:Animal(){cout<<"父类Animal无参构造了"<<endl;}Animal(int m){cout<<"父类Animal带int类型参数构造了,参数是: "<<m<<endl;}
};
class Cat:public Animal
{
public:Cat():Animal(123){cout<<"子类Cat无参构造了"<<endl;}Cat(int n){cout<<"子类Cat带int参数构造了"<<endl;}Cat(int n,string name):Animal(1258){cout<<"子类Cat带int和string参数构造了"<<endl;}
};int main(int argc,char **argv)
{Cat c1;Cat c2(666);Cat c3(888,"旺财");return 0;   
}/*
执行结果父类Animal带int类型参数构造了,参数是: 123   ----->在子类构造函数进行指定子类Cat无参构造了父类Animal无参构造了子类Cat带int参数构造了父类Animal带int类型参数构造了,参数是: 1258 ----->在子类构造函数进行指定子类Cat带int和string参数构造了
*/

4.构造函数的调用

  • 写法一:
    Animal a; //注意:写成Animal a()这样子不正确,编译没有错,但是不会调用无参构造函数
    但是:Animal *p=new Animal() //这两种都可以调用无参构造函数
    Animal *p=new Animal; //这两种都可以调用无参构造函数

  • 写法二:
    Animal a(15);

  • 写法三:
    Animal a=Animal(15); //初始化语句

  • 写法四:
    Animal a;
    a=Animal(18); //赋值语句 Animal(18)会创建一个临时对象,然后把临时对象赋值给a

  • 写法五:
    Animal a={“小黄”,5}; C++11列表初始化
    Animal b {“旺财”,7};
    Animal c {};

相关文章:

【C++】类的构造函数

类的构造函数 1. 作用&#xff1a;2.语法规则&#xff1a;示例代码&#xff1a;构造函数语法 2.1 特点&#xff1a;示例代码&#xff1a;自定义了构造函数&#xff0c;系统不会再生成默认构造函数示例代码&#xff1a;构造函数重载 3.构造函数常见的写法3.1 无参构造函数3.2 带…...

【ISP算法精粹】动手实战:用 Python 实现 Bayer 图像的黑电平校正

在数字成像领域&#xff0c;图像信号处理器&#xff08;ISP&#xff09;如同幕后英雄&#xff0c;默默将传感器捕获的原始数据转化为精美的图像。而黑电平校正&#xff0c;作为ISP预处理流程中的关键一环&#xff0c;直接影响着最终图像的质量。今天&#xff0c;我们就通过Pyth…...

分布式存储技术全景解析:从架构演进到场景实践

目录 技术演进与市场新格局核心架构设计深度剖析前沿技术创新与性能突破行业应用场景实践挑战与未来发展趋势1. 技术演进与市场新格局 1.1 从集中式到分布式的范式转移 传统集中式存储(如NAS/SAN)在扩展性和容错性方面面临根本性瓶颈,而分布式存储通过水平扩展架构和多节点…...

JVM——从JIT到AOT:JVM编译器的云原生演进之路

引入 在Java的世界里&#xff0c;一段代码从开发者手中的文本到计算机执行的机器指令&#xff0c;需要跨越"字节码"这座桥梁。而JVM编译器正是架起这座桥梁的工程师&#xff0c;它的每一次技术演进都推动着Java性能的跃迁。从早期逐行翻译的解释器&#xff0c;到智能…...

Linux中的mysql逻辑备份与恢复

一、安装mysql社区服务 二、数据库的介绍 三、备份类型和备份工具 一、安装mysql社区服务 这是小编自己写的&#xff0c;没有安装的去看看 Linux换源以及yum安装nginx和mysql-CSDN博客 二、数据库的介绍 2.1 数据库的组成 数据库是一堆物理文件的集合&#xff0c;主要包括…...

[HTML5]快速掌握canvas

背景 canvas 是 html5 标准中提供的一个标签, 顾名思义是定义在浏览器上的画布 通过其强大的绘图接口&#xff0c;我们可以实现各种各样的图形&#xff0c;炫酷的动画&#xff0c;甚至可以利用他开发小游戏&#xff0c;包括市面上很流行的数据可视化框架底层都用到了Canvas。…...

Gartner《Emerging Patterns for Building LLM-Based AIAgents》学习心得

一、AI代理概述 2024年,AI代理成为市场热点,它们能自主规划和行动以实现用户目标,与仅能感知、决策、行动和达成目标的AI助手及聊天机器人有本质区别。Gartner定义的AI代理是使用AI技术在数字或物理环境中自主或半自主运行的软件实体。 二、LLM基础AI代理的特性和挑战 优势…...

Hive SQL优化实践:提升大数据处理效率的关键策略

在大数据生态中&#xff0c;Hive作为基于Hadoop的数据仓库工具&#xff0c;广泛应用于海量数据的离线分析场景。然而&#xff0c;随着数据量的指数级增长和业务复杂度的提升&#xff0c;低效的Hive SQL可能导致资源浪费和查询性能瓶颈。本文将从存储优化、计算优化、资源配置三…...

vue中父子参数传递双向的方式不同

在面试中被问到。平时也有用到&#xff0c;但是缺少总结 父传子。父页面会给子页面中定义的props属性传参&#xff0c;子页面接收子传父。父页面需要监听事件来接收子页面通过$emit发送的消息其实说的以上两种都是组件之间传递。还可以通过路由传参, 状态管理器的方式传递 下面…...

LLM 使用 MCP 协议及其原理详解

LLM 使用 MCP 协议及其原理详解 &#x1f9e0; 一、MCP 协议概述 1. MCP 是什么&#xff1f; MCP&#xff08;Modular Communication Protocol&#xff09;是一种面向语言模型设计的通用通信协议&#xff0c;其设计目标是&#xff1a; 模块化&#xff08;Modular&#xff0…...

DAY 36神经网络加速器easy

仔细回顾一下神经网络到目前的内容&#xff0c;没跟上进度的同学补一下进度。 ●作业&#xff1a;对之前的信贷项目&#xff0c;利用神经网络训练下&#xff0c;尝试用到目前的知识点让代码更加规范和美观。 ●探索性作业&#xff08;随意完成&#xff09;&#xff1a;尝试进入…...

STM32 单片机启动过程全解析:从上电到主函数的旅程

一、为什么要理解启动过程&#xff1f; STM32 的启动过程就像一台精密仪器的开机自检&#xff0c;它确保所有系统部件按既定方式初始化&#xff0c;才能顺利运行我们的应用代码。对初学者而言&#xff0c;理解启动过程能帮助解决常见“程序跑飞”“不进 main”“下载后无反应”…...

4.RV1126-OPENCV 图像轮廓识别

一.图像识别API 1.图像识别作用 它常用于视觉任务、目标检测、图像分割等等。在 OPENCV 中通常使用 Canny 函数、findContours 函数、drawContours 函数结合在一起去做轮廓的形检测。 2.常用的API findContours 函数&#xff1a;用于寻找图片的轮廓&#xff0c;并把所有的数…...

WEB3——开发者怎么查看自己的合约日志记录

在区块链中查看合约的日志信息&#xff08;也叫事件 logs&#xff09;&#xff0c;主要有以下几种方式&#xff0c;具体方法依赖于你使用的区块链平台&#xff08;如 Ethereum、BSC、Polygon 等&#xff09;和工具&#xff08;如 Etherscan、web3.js、ethers.js、Hardhat 等&am…...

TDengine 集群容错与灾备

简介 为了防止数据丢失、误删操作&#xff0c;TDengine 提供全面的数据备份、恢复、容错、异地数据实时同步等功能&#xff0c;以保证数据存储的安全。本节简要说明 TDengine 中的容错与灾备。 容错 TDengine 支持 WAL 机制&#xff0c;实现数据的容错能力&#xff0c;保证数…...

MG影视登录解锁永久VIP会员 v8.0 支持手机电视TV版影视直播软件

MG影视登录解锁永久VIP会员 v8.0 支持手机电视TV版影视直播软件 MG影视App电视版是一款资源丰富、免费便捷、且专为大屏优化的影视聚合应用&#xff0c;聚合海量资源&#xff0c;畅享电视直播&#xff0c;是您电视盒子和…...

如何成为一名优秀的产品经理(自动驾驶)

一、 夯实核心基础 深入理解智能驾驶技术栈&#xff1a; 感知&#xff1a; 摄像头、雷达&#xff08;毫米波、激光雷达&#xff09;、超声波传感器的工作原理、优缺点、融合策略。了解目标检测、跟踪、SLAM等基础算法概念。 定位&#xff1a; GNSS、IMU、高精地图、轮速计等定…...

BAT脚本编写详细教程

目录 第一部分:BAT脚本简介第二部分:创建和运行BAT脚本第三部分:基本命令和语法第四部分:变量使用第五部分:流程控制第六部分:函数和子程序第七部分:高级技巧第八部分:实用示例第一部分:BAT脚本简介 BAT脚本(批处理脚本)是Windows操作系统中的一种脚本文件,扩展名…...

快速了解 GO之接口解耦

更多个人笔记见&#xff1a; &#xff08;注意点击“继续”&#xff0c;而不是“发现新项目”&#xff09; github个人笔记仓库 https://github.com/ZHLOVEYY/IT_note gitee 个人笔记仓库 https://gitee.com/harryhack/it_note 个人学习&#xff0c;学习过程中还会不断补充&…...

【多线程初阶】内存可见性问题 volatile

文章目录 再谈线程安全问题内存可见性问题可见性问题案例编译器优化 volatileJava内存模型(JMM) 再谈线程安全问题 如果多线程环境下代码运行的结果是符合我们预期的,即在单线程环境应该有的结果,则说这个程序是线程安全的,反之,多线程环境中,并发执行后,产生bug就是线程不安全…...

C++ 类模板三参数深度解析:从链表迭代器看类型推导与实例化(为什么迭代器类模版使用三参数?实例化又会是怎样?)

本篇主要续上一篇的list模拟实现遇到的问题详细讲解&#xff1a;<传送门> 一、引言&#xff1a;模板参数的 "三角锁钥" 在 C 双向链表实现中&#xff0c;__list_iterator类模板的三个参数&#xff08;T、Ref、Ptr&#xff09;如同精密仪器的调节旋钮&#x…...

MySQL强化关键_018_MySQL 优化手段及性能分析工具

目 录 一、优化手段 二、SQL 性能分析工具 1.查看数据库整体情况 &#xff08;1&#xff09;语法格式 &#xff08;2&#xff09;说明 2.慢查询日志 &#xff08;1&#xff09;说明 &#xff08;2&#xff09;开启慢查询日志功能 &#xff08;3&#xff09;实例 3.s…...

ASP.NET MVC添加模型示例

ASP.NET MVC高效构建Web应用ASP.NET MVC 我们总在谈“模型”&#xff0c;那到底什么是模型&#xff1f;简单说来&#xff0c;模型就是当我们使用软件去解决真实世界中各种实际问题的时候&#xff0c;对那些我们关心的实际事物的抽象和简化。比如&#xff0c;我们在软件系统中设…...

【Part 3 Unity VR眼镜端播放器开发与优化】第二节|VR眼镜端的开发适配与交互设计

文章目录 《VR 360全景视频开发》专栏Part 3&#xff5c;Unity VR眼镜端播放器开发与优化第一节&#xff5c;基于Unity的360全景视频播放实现方案第二节&#xff5c;VR眼镜端的开发适配与交互设计一、Unity XR开发环境与设备适配1.1 启用XR Plugin Management1.2 配置OpenXR与平…...

第1天:认识RNN及RNN初步实验(预测下一个数字)

RNN&#xff08;循环神经网络&#xff09; 是一种专门设计用来处理序列数据的人工神经网络。它的核心思想是能够“记住”之前处理过的信息&#xff0c;并将其用于当前的计算&#xff0c;这使得它非常适合处理具有时间顺序或上下文依赖关系的数据。 核心概念&#xff1a;循环连…...

全文索引详解及适用场景分析

全文索引详解及适用场景分析 1. 全文索引基本概念 1.1 定义与核心原理 全文索引(Full-Text Index)是一种特殊的数据库索引类型,专门设计用于高效处理文本数据的搜索需求。与传统的B树索引不同,全文索引不是基于精确匹配,而是通过建立倒排索引(Inverted Index)结构来实现对…...

利用DeepSeek编写能在DuckDB中读PostgreSQL表的表函数

前文实现了UDF和UDAF&#xff0c;还有一类函数是表函数&#xff0c;它放在From 子句中&#xff0c;返回一个集合。DuckDB中已有PostgreSQL插件&#xff0c;但我们可以用pqxx库实现一个简易的只读read_pg()表函数。 提示词如下&#xff1a; 请将libpqxx库集成到我们的程序&#…...

树莓派安装openwrt搭建软路由(ImmortalWrt固件方案)

&#x1f923;&#x1f449;我这里准备了两个版本的openwrt安装方案给大家参考使用&#xff0c;分别是原版的OpenWrt固件以及在原版基础上进行改进的ImmortalWrt固件。推荐使用ImmortalWrt固件&#xff0c;当然如果想直接在原版上进行开发也可以&#xff0c;看个人选择。 &…...

排序算法——详解

排序算法 &#xff08;冒泡、选择、插入、快排、归并、堆排、计数、桶、基数&#xff09; 稳定性 (Stability): 如果排序算法能保证&#xff0c;当待排序序列中存在值相等的元素时&#xff0c;排序后这些元素的相对次序保持不变&#xff0c;那么该算法就是稳定的。 例如&#…...

Go整合Redis2.0发布订阅

Go整合Redis2.0发布订阅 Redis goredis-cli --version redis-cli 5.0.14.1 (git:ec77f72d)Go go get github.com/go-redis/redis/v8package redisimport ("MyKindom-Server-v2.0/com/xzm/core/config/yaml""MyKindom-Server-v2.0/com/xzm/core/config/yaml/po…...