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++转换

#include <iostream> #include <stdlib.h> using namespace std; int main(void){     cout << "请输入一个整数:" << endl;     int x = 0;     cin >> x;     cout <<"  八进制:"<< oct << x << endl;

Xcode缺少libstdc++的解决方案

Xcode 10和Xcode 11中删除的libstdc++库 先下载下来这个项目,然后打开终端cd到libstdc文件夹; 如果你使用的是 Xcode 10,则将install-Xcode_10.sh拖到终端中执行即可。Xcode 11 版则将install-Xcode_11.sh拖到终端中执行。

【LinuxC++】Linux环境下C++编程

在阅读的过程中有任何问题,欢迎一起交流 邮箱:1494713801@qq.com   QQ:1494713801   在linux下,开发工具被切割成一个个独立的小工具。各自处理不同的问题。例如: 编辑器(emacs, vim)用来进行编辑程序的 调试器(gdb) 用来调试程序 编译器(GCC) 用来编译和链接程序的 性能分析工具(gcov, gprof) 用来优化程序的 文档生成器

C++ 结构体内存对齐

定义了两个结构体 typedef struct Cmd {uint8_t ua;uint8_t ub;uint8_t uc;uint32_t ue;} Cmd_t;typedef struct Cmd_tag {uint8_t value;uint8_t data[1]; // 将 data 定义为指向 Cmd_t 结构体的指针} tag_t; 在实际使用中,看见前人的代码是,new

sublime text 3 配置GCC G++编译C C++文件

这个博主真是好!写的好详细 ,就是在sublime下关于中文编码问题不太好!C / C++下sublime 默认中文编码为utf-8,而cmd中是gbk编码。所以在sublime中写的中文在cmd中显示会乱码,就算配置了也不如vs这类IDE方便。然而sublime小巧真是讨喜啊! 点击打开链接

red_black_tree的一个实现(c/c++)

参考《STL源码剖析》, 博客:http://blog.csdn.net/spch2008/article/details/9338923 #ifndef MY_RB_TREE_H#define MY_RB_TREE_H#include<iostream>#include<cstddef>using namespace std;#define t_classes <typename K

【OpenCV C++】cvtColor将彩色图像转换为灰度图时,3个通道的灰度值是如何处理的? 三个通道是如何加权计算的?三个通道取平均得到灰度图吗?

文章目录 在OpenCV中,使用cv::cvtColor函数将彩色图像转换为灰度图时,3个通道的灰度值并不是简单地取平均值,而是通过加权平均的方法来计算的。 具体来说,灰度值是根据人眼对不同颜色敏感度的不同,使用加权公式计算得到的。 转换公式 通常使用的加权公式是: Gray=0.299×R+0.587×G+0.114×B 解释 R、G、B 分别代表红色、绿色和蓝色通道的

C++中的RAII机制介绍

C++中的RAII机制 https://www.jianshu.com/p/b7ffe79498be https://zhuanlan.zhihu.com/p/335565835 https://zhuanlan.zhihu.com/p/34660259 RAll(Resource Acquisition Is Initialization)是由c++之父Bjarne S

C++进阶之路:何为默认构造函数与析构函数(类与对象_中篇)

✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭❤~✨✨ 🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢,在这里我会分享我的知识和经验。🎥 希望在这里,我们能一起探索IT世界的奥妙,提升我们的技能。🔮 记得先点赞👍后阅读哦~ 👏👏 📘📚 所属专栏:C/C++ 欢迎访问我的主页:Srlua小谢 获取更多信息和资源。✨✨🌙🌙 ​​​

C++之lambda【匿名函数】

1、语法 语法结构: [捕获列表](参数列表) mutable(可选) 异常属性 -> 返回类型 {// 函数处理} 注意:         一般情况下,编译器可以自动推断出lambda表达式的返回类型,所以我们可以不指定返回类型。         但是如果函数体内有多个return语句时,编译器无法自动推断出返回类型,此时必须指定返回类型。 代码: #include <iost