Week8-C++基础3(构造函数、静态成员函数和变量、运算符重载学习)

本文主要是介绍Week8-C++基础3(构造函数、静态成员函数和变量、运算符重载学习),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、构造函数及析构函数
1、构造函数:没有返回值 没有void,类名相同,可以发生重载,可以有参数2、析构函数:没有返回,没有void ,函数名称: ~类名,不可以发生重载,不可以有参数
①按照构造函数的类型分类-----默认/无参构造函数、有参构造函数还有拷贝构造函数
②按照构造函数调用方法分类-----括号法调用、显示法调用
具体示例如下;

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;class Person
{
public: //构造和析构必须写在public下才可以调用到Person() //默认 、 无参构造函数{cout << "默认构造函数调用" << endl;}Person(int a){cout << "有参构造函数调用" << endl;}//拷贝构造函数Person(const Person& p){m_Age = p.m_Age;cout << "拷贝构造函数调用" << endl;}~Person(){cout << "析构函数调用" << endl;}int m_Age;
};void test01()
{//构造函数调用方式//括号法调用Person p1(1); //有参p1.m_Age = 10;Person p2(p1); //拷贝cout << "p2的年龄" << p2.m_Age << endl;Person p3; //默认构造函数 不要加()   Person p3(); //编译器认为这行是函数的声明//显示法调用Person p4 = Person(100);Person p5 = Person(p4);Person(100); //叫匿名对象 ,匿名对象特点,如果编译器发现了对象是匿名的,那么在这行代码结束后就释放这个对象//不能用拷贝构造函数 初始化匿名对象//Person p6 = Person(p5); //如果写成左值,编译器认为你写成 Person p5; 对象的声明,如果写成右值,那么可以Person p7 = 100; //相当于调用了 Person p7 = Person(100) ,隐式类型转换Person p8 = p7; // 相当于  Person p8 = Person(p7);
}int main() {test01();system("pause");return EXIT_SUCCESS;
}

运行结果如图
在这里插入图片描述
3、构造函数的调用规则
①如果提供了有参的构造,那么系统就不会提供默认的构造了,但是会提供拷贝构造
②如果提供了拷贝构造函数,那么系统就不会提供其他的构造函数了
4、深拷贝与浅拷贝
①系统默认提供的拷贝构造 会进行简单的值拷贝
②如果属性里有指向堆区空间的数据,那么简单的浅拷贝会导致重复释放内存的异常,解决上述问题,需要我们自己提供拷贝构造函数,进行深拷贝
5、其他补充
①初始化列表:在构造函数后面 + : 属性(值、参数), 属性(值、参数)…

Person(int a, int b, int c) : m_A(a), m_B(b), m_C(c){}

②explicit关键字 作用:防止构造函数中的隐式类型转换
③new 运算符 和 delete运算符(new类似于malloc,delete类似于free),具体使用代码如下

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;class Person
{
public:Person(){cout << "默认构造调用" << endl;}Person(int a){cout << "有参构造调用" << endl;}~Person(){cout << "析构函数调用" << endl;}};void test01()
{//Person p1;  栈区开辟Person* p2 = new Person; //堆区开辟//所有new出来的对象 都会返回该类型的指针//malloc不会调用构造吗  new会调用构造delete p2;}void test02()
{void* p = new Person(10);//当用void* 接受new出来的指针 ,会出现释放的问题delete p;//无法释放p ,所以避免这种写法
}void test03()
{//通过new开辟数组 一定会调用默认构造函数,所以一定要提供默认构造Person* pArray = new Person[10];//Person pArray2[2] = { Person(1), Person(2) }; //在栈上开辟数组,可以指定有参构造//释放数组 delete []delete[] pArray;
}int main() {//test01();//test02();test03();system("pause");return EXIT_SUCCESS;
}

二、静态成员变量和静态成员函数
1、 静态成员变量
① 编译阶段分配内存
② 所有对象共享数据
③ 有权限控制
④ 类内声明 类外初始化
2、 静态成员函数
① 可以访问静态成员变量,不可以方法普通成员变量
② 普通成员函数 都可以访问
③ 静态成员函数也有权限
④ 可以通过对象访问,也可以通过类名进行访问
具体代码示例如下

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;class Person
{
public:Person(){//m_Age = 10;}static int m_Age; //加入static就是 静态成员变量 ,会共享数据//静态成员变量,在类内声明,类外进行初始化//静态成员变量 也是有权限的int m_A;//静态成员函数//不可以访问  普通成员变量//可以访问 静态成员变量static void func(){//m_A = 10;m_Age = 100;cout << "func调用" << endl;};//普通成员函数 可以访问普通成员变量,也可以访问静态成员变量void myFunc(){m_A = 100;m_Age = 100;}
private:static int m_other; //私有权限 在类外不能访问static void func2(){cout << "func2调用" << endl;}
};
int  Person::m_Age = 0; //类外初始化实现
int  Person::m_other = 10;void test01()
{//1 通过对象访问属性Person p1;p1.m_Age = 10;Person p2;p2.m_Age = 20;cout << "p1 = " << p1.m_Age << endl; //10 或者 20? 20cout << "p2 = " << p2.m_Age << endl; //20//共享数据//2 通过类名访问属性cout << "通过类名访问Age" << Person::m_Age << endl;//cout << "other = " << Person::m_other << endl; //私有权限在类外无法访问//静态成员函数调用p1.func();p2.func();Person::func();//静态成员函数 也是有权限的//Person::func2();}int main() {test01();system("pause");return EXIT_SUCCESS;
}

运行结果如图
在这里插入图片描述
3、this指针的使用
① 指针永远指向当前对象
② 解决命名冲突
③ *this 指向对象本体
④ 非静态的成员函数才有this指针
4常函数和常对象
① 常函数 void func() const {} 常函数
② 常函数 修饰是this指针 const Type * const this
③ 常函数 不能修改this指针执行的值
④ 常对象 在对象前 加入 const修饰 const Person p1
⑤ 常对象 不可以调用普通的成员函数
⑥ 常对象 可以调用常函数
⑦ 用mutable修饰的关键字是在常函数可以修改的
5、友元(friend)
① 全局函数做友元函数
(全局函数写到 类中做声明 并且最前面写关键字 friend)
② 让整个类 做友元类
( friend class 类名 )
( 友元类 是单向,不可传递的)
③ 让成员函数做友元函数
( friend void goodGay::visit();)
三、运算符重载(举单一例子)
1、加号运算符重载
① 如果想让自定义数据类型 进行+运算,那么就需要重载 + 运算符
② 在成员函数 或者 全局函数里 重写一个+运算符的函数
③ 函数名 operator+ () {}(其他运算符的话把+改掉)
④ 运算符重载 也可以提供多个版本
具体代码示例如下

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;class Person
{
public:Person() {};Person(int a, int b) :m_A(a), m_B(b){}//+号运算符重载 成员函数 二元/*Person operator+ ( Person & p){Person tmp;tmp.m_A = this->m_A + p.m_A;tmp.m_B = this->m_B + p.m_B;return tmp;}*/int m_A;int m_B;
};//利用全局函数 进行+号运算符的重载
Person operator+ (Person& p1, Person& p2) //二元  p1 + p2   
{Person tmp;tmp.m_A = p1.m_A + p2.m_A;tmp.m_B = p1.m_B + p2.m_B;return tmp;
}Person operator+ (Person& p1, int a) //二元
{Person tmp;tmp.m_A = p1.m_A + a;tmp.m_B = p1.m_B + a;return tmp;
}void test01()
{Person p1(10, 10);Person p2(10, 10);Person p3 = p1 + p2; // p1 + p2  从什么表达式转变的? p1.operator+(p2)  operator+(p1,p2)Person p4 = p1 + 10; //重载的版本cout << "p3 的 m_A: " << p3.m_A << "  m_B: " << p3.m_B << endl;//operator+(p1, p2);}int main() {test01();system("pause");return EXIT_SUCCESS;
}

运行结果如图
在这里插入图片描述
欢迎关注技术公众号,获取更多软件学习干货!
在这里插入图片描述

我们能为你提供什么?
技术辅导:C++、Java、嵌入式软件/硬件
项目辅导:软件/硬件项目、大厂实训项目
就业辅导:就业全流程辅导、技术创业支持
对接企业HR:培养输送优质性人才

这篇关于Week8-C++基础3(构造函数、静态成员函数和变量、运算符重载学习)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

【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 是一个通用的函数包装器,它可以存储任意可调用对象(函数、函数

hdu1171(母函数或多重背包)

题意:把物品分成两份,使得价值最接近 可以用背包,或者是母函数来解,母函数(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v) 其中指数为价值,每一项的数目为(该物品数+1)个 代码如下: #include<iostream>#include<algorithm>

变量与命名

引言         在前两个课时中,我们已经了解了 Python 程序的基本结构,学习了如何正确地使用缩进来组织代码,并且知道了注释的重要性。现在我们将进一步深入到 Python 编程的核心——变量与命名。变量是我们存储数据的主要方式,而合理的命名则有助于提高代码的可读性和可维护性。 变量的概念与使用         在 Python 中,变量是一种用来存储数据值的标识符。创建变量很简单,

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对象