c++类之揭开构造函数之谜篇

2024-05-05 18:18
文章标签 c++ 构造函数 揭开 之谜

本文主要是介绍c++类之揭开构造函数之谜篇,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

构造函数篇

什么是构造函数?

跟他的名字一样,当类被实例化的那一刻立马被执行!!

特点: 无返回值,记住是无。不是返回void,函数名和类名一样!每个类中至少有一个!当没有显式定义构造函数,编译器自动为类添加一个无参数,无返回值的构造函数;这个构造函数称为: 默认构造函数

举例如下:

class CRole
{
public:CRole();  //这个为构造函数!const char* Name;int Hp;int Mp;int Damage;void Fight(CRole& c);
};

如何显式设置默认构造

1、利用default关键字

class CRole
{
public:CRole()=default;  //显式声明为默认构造const char* Name;int Hp;int Mp;int Damage;void Fight(CRole& c);
};

2、强行放一个无参的构造上去

class CRole
{
public:CRole();  //这个为构造函数!const char* Name;int Hp;int Mp;int Damage;void Fight(CRole& c);
};

区别: 当我们构造中需要进行初始化一些操作,我们就得用第二种了!当构造中什么都不做的时候可以用第一种,第一种效率更高。至于原因留给你们发掘!!

副本构造函数

当我们出现一下的赋值方式时:

//声明类似这个
CRole(CRole& r);  //这里必须为引用,至于为什么大家自行百度,挺复杂
//实现如下
CRole::CRole(CRole& r)
{Hp= r.Hp;Mp = r.Mp;Damage = r.Damage;lv = r.lv;cout << "CRole(CROle&)" << endl;
}int main()
{CRole user;cout << user.Hp << " " << user.lv << endl;CRole mon(user); //用此方式实例化时,就会执行副本构造函数cout << mon.Hp << " " << mon.lv << endl;
}

结果:
在这里插入图片描述
这里就可以看到直接定义不加任何修饰调用默认构造,而()进行定义时调用副本构造

下面通过一段代码来说明副本构造一个常见坑:

//副本构造为这样
CRole(int _lv = 500);
//有一成员函数这样,用来判断是否()内等级高于自己,高就返回1,否则0
bool IsHigh(CRole rl);//main函数为这样
int main()
{CRole user(100);   //等级为100CRole monster(200);  //等级为200cout << user.IsHigh(monster) << endl;
}

来看一下结果:
在这里插入图片描述
结果似乎好像对的;
我们再看:

int main()
{CRole user(100); CRole monster(200); cout << user.IsHigh(200) << endl;  //改成这样
}

再看结果:
在这里插入图片描述
竟然也是对的!!我们大概能够猜到,这里面经历了以此隐式类型转换和一次构造调用,细节暂且不去追究,就是这样的局面!非常尴尬,明明要求式role类型,给它整形数字答案也是对的,很可怕!!那么如何解决这种问题呢?(情境是硬凑的!哈哈,尴尬)
请看下面:↓

explicit关键字

**作用:**被之修饰的构造函数会禁用类型转换!

//原来的
CRole(int _lv = 500);
//修改后
explicit CRole(int _lv = 500);

再看结果:
在这里插入图片描述
大功告成!!!

构造函数里初始化列表运用
	//类这样就ok了//lv和Damage是类成员变量CRole(int _lv, int _damage) :lv{ _lv }, Damage{ _damage }{}

优势: 效率比在大括号内一行一行赋值效率高;

不足:

利用初始化列表构造类时,成员的赋值顺序不是代码从左到右排列的顺序,而是成员变量在类中出现的顺序!!!这点要格外注意!

举个例子:

class CRole
{
public:int Hp;  //hp在lv之前int Mp;int Damage;int lv;CRole(int _hp, int _lv, int _damage) :lv{ _lv }, Damage{ _damage }, Hp{ 10 * lv }{}
};int main()
{//---------血量  等级 伤害CRole user(100, 50, 10);cout << user.Hp << " " << user.lv << " " << user.Damage << endl;
}

来看看结果!!!
在这里插入图片描述
是不是很意外?原因就是Hp由10*lv而来,但是它的顺序是hp先赋值,所以自然跟预期不符!

简单调整一下成员变量顺序就可用了:

class CRole
{
public:int lv;  //lv在hp之前int Hp;int Mp;int Damage;CRole(int _hp, int _lv, int _damage) :lv{ _lv }, Damage{ _damage }, Hp{ 10 * lv }{}
};

结果:
在这里插入图片描述
是不是有对了呢?哈哈,c++真刺激!!!

委托构造?

委托构造是什么呢?就是用一个构造直接类似于初始化列表一下一个:放那!!!
不懂的话举个例子就ok了!

class CRole
{
public:int lv;int Hp;int Mp;int Damage;CRole() :CRole(20, 50)  //这里就是委托构造{} CRole(int _hp, int _lv) :lv{ _lv }, Hp{_hp} {}
};

感谢自己努力拼搏的学习!!!老铁们觉得有点用的话,记得点点赞哦!!!我是航行的小土豆!!!

这篇关于c++类之揭开构造函数之谜篇的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/962349

相关文章

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

C++包装器

包装器 在 C++ 中,“包装器”通常指的是一种设计模式或编程技巧,用于封装其他代码或对象,使其更易于使用、管理或扩展。包装器的概念在编程中非常普遍,可以用于函数、类、库等多个方面。下面是几个常见的 “包装器” 类型: 1. 函数包装器 函数包装器用于封装一个或多个函数,使其接口更统一或更便于调用。例如,std::function 是一个通用的函数包装器,它可以存储任意可调用对象(函数、函数

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

06 C++Lambda表达式

lambda表达式的定义 没有显式模版形参的lambda表达式 [捕获] 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 有显式模版形参的lambda表达式 [捕获] <模版形参> 模版约束 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 含义 捕获:包含零个或者多个捕获符的逗号分隔列表 模板形参:用于泛型lambda提供个模板形参的名

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

【C++高阶】C++类型转换全攻略:深入理解并高效应用

📝个人主页🌹:Eternity._ ⏩收录专栏⏪:C++ “ 登神长阶 ” 🤡往期回顾🤡:C++ 智能指针 🌹🌹期待您的关注 🌹🌹 ❀C++的类型转换 📒1. C语言中的类型转换📚2. C++强制类型转换⛰️static_cast🌞reinterpret_cast⭐const_cast🍁dynamic_cast 📜3. C++强制类型转换的原因📝

C++——stack、queue的实现及deque的介绍

目录 1.stack与queue的实现 1.1stack的实现  1.2 queue的实现 2.重温vector、list、stack、queue的介绍 2.1 STL标准库中stack和queue的底层结构  3.deque的简单介绍 3.1为什么选择deque作为stack和queue的底层默认容器  3.2 STL中对stack与queue的模拟实现 ①stack模拟实现

c++的初始化列表与const成员

初始化列表与const成员 const成员 使用const修饰的类、结构、联合的成员变量,在类对象创建完成前一定要初始化。 不能在构造函数中初始化const成员,因为执行构造函数时,类对象已经创建完成,只有类对象创建完成才能调用成员函数,构造函数虽然特殊但也是成员函数。 在定义const成员时进行初始化,该语法只有在C11语法标准下才支持。 初始化列表 在构造函数小括号后面,主要用于给

2024/9/8 c++ smart

1.通过自己编写的class来实现unique_ptr指针的功能 #include <iostream> using namespace std; template<class T> class unique_ptr { public:         //无参构造函数         unique_ptr();         //有参构造函数         unique_ptr(