C++(学习)2024.9.19

目录

面向对象基础

类与对象

概念

类的内容

创建对象

封装

构造函数

基本使用

构造初始化列表

隐式调用与显式调用

拷贝构造函数

浅拷贝

 深拷贝

析构函数

作用域限定符:

名字空间

类内声明,类外定义

面向对象基础

类与对象

概念

类:类是一个抽象的概念,用于描述同一类对象的特点。
对象:根据类的概念所创造的实体。

必须要先写类才能创建对象。

类的内容

类中最基础的内容包括两个部分,一个是属性,一个是行为。
属性:表示一些特征项的数值,比如说:身高、体重、肤色、性别、重量、颜色、型号等等。而这些特征项的数值也被称为成员变量。属性一般以名词存在。
行为:表示能执行的动作,能干什么事?比如说:吃饭、睡觉、打架、打篮球。行为一般函数实现,也被称为成员函数。行为一般以动词存在。

成员 = 成员函数+成员变量。

class MobilePhone// 帕斯卡命名法(大驼峰命名法)
{
public: string brand;   // 品牌string model;   // 型号int weight; // 重量void play_music(){cout << "音乐ing" << endl;}void run_game(){cout << "LOL、原神、王者荣耀、开心消消乐、" << endl;}void call(){cout << "hello" << endl;}
};

创建对象

1.栈内存对象

#include <iostream>
using namespace std;
int main()
{MobilePhone mp;mp.brand = "xiaomi";mp.model = "11 Pro";mp.weight = 200;cout << mp.brand << " " << mp.model << " " << mp.weight << " " << endl;mp.play_music();mp.run_game();mp.call();return 0;
}

2.堆内存对象

        必须使用new关键字创建,使用指针保存。如果不使用delete关键字销毁,则堆内存对象会持续存在。而导致内存泄漏。堆内存对象在调用成员时,使用->而不是"."

#include <iostream>
using namespace std;
int main()
{MobilePhone* mp = new MobilePhone;  // 堆内存对象mp->brand = "huawei";mp->model = "mate 30";mp->weight = 200;cout << mp->brand << " " << mp->model << " " << mp->weight << endl;mp->play_music();mp->run_game();mp->call();delete mp;  // 手动销毁mp = NULL; return 0;
}

封装

        类与结构体差别不大,实际上可以认为结构体就是一种完全开放的类。
        封装指的是,将类的一些属性和细节隐藏。重新提供外部访问接口,封装可以提升代码的安全性,并且可以让程序员更关注于上层架构而非内部细节。

#include <iostream>
using namespace std;
class MobilePhone
{
private:    // 私有权限,private是最封闭的权限,只能在类内访问string brand;   // 品牌string model;   // 型号int weight = 200; // 重量public: // 权限:public最开放的权限// geter 读函数string get_brand(){return brand;}// seter 写函数void set_brand(string b){brand = b;}// 读函数string get_model(){return model;}// seter 写函数void set_model(string m){model = m;}// getint get_weight(){return weight;}
};int main()
{MobilePhone mp1;    // 栈内存对象mp1.set_brand("pingguo");mp1.set_model("15 Pro");cout << mp1.get_brand() << " " << mp1.get_model() << " " << mp1.get_weight() << endl;MobilePhone *mp2 = new MobilePhone; // 堆内存对象mp2->set_brand("pingguo");mp2->set_model("16 pro");cout << mp2->get_brand() << " " << mp2->get_model() << " " << mp2->get_weight() << endl;return 0;
}

构造函数

基本使用

构造函数是一种特殊的成员函数,用于创建对象时初始化。创建对象时必须直接或者间接调用当前类的任意一个构造函数。

构造函数写法上有以下要求:

        1.函数名称必须与类名完全相同
        2.构造函数不写返回值
        3.如果程序员不手动编写构造函数,编译器会自动添加一个默认的无参数的构造函数,只要添加任意构造函数后,编译器将不再补充默认无参数的构造函数。

        构造函数在创建对象时,常用于给对象的属性赋予初始值。构造函数也支持函数重载,构造函数也支持函数参数默认值

#include <iostream>
using namespace std;class MyPhone{
private:string pinpai;//品牌string xinghao;//型号int zhongliang;//重量public:MyPhone(){cout <<"调用无参构造函数"<<endl;pinpai="小米";xinghao="11 Pro";zhongliang=205;}MyPhone(string a,string b,int c){cout <<"调用有参构造函数"<<endl;pinpai=a;xinghao=b;zhongliang=c;}string getPinpai(){return pinpai;}void setPinpai(string value){pinpai = value;}string getXinghao(){return xinghao;}void setXinghao(string value){xinghao = value;}int getZhongliang(){return zhongliang;}
};int main()
{MyPhone *mp=new MyPhone("苹果","16 Pro",200);cout <<"手机为"<<mp->getPinpai()<<" "<<mp->getXinghao()<<" 重量为:"<<mp->getZhongliang()<<"g"<<endl;delete mp;mp=NULL;MyPhone a;cout <<"手机为"<<a.getPinpai()<<" "<<a.getXinghao()<<" 重量为:"<<a.getZhongliang()<<"g"<<endl;return 0;
}

构造初始化列表

构造初始化列表是一种更简单的给成员变量赋予初始值的写法。

#include <iostream>
using namespace std;
class MobilePhone
{
private:   string brand;  string model;   int weight;
public: MobilePhone():brand("8848"),model("M6巅峰版"),weight(300){}MobilePhone(string b,string m,int w):brand(b),model(m),weight(w){}string get_brand(){return brand;}string get_model(){return model;}int get_weight(){return weight;}
};int main()
{MobilePhone mp1("小米","su7",300); cout << mp1.get_brand() << " " << mp1.get_model() << " " << mp1.get_weight() << endl;return 0;
}

当构造函数的局部变量与成员变量重名时,除了使用后面学习的this指针的方式外,还可以使用构造初始化列表区分。

隐式调用与显式调用

构造函数的调用可以分为显式调用与隐式调用。
        显式调用是指在创建对象时手写构造函数的名称,与参数列表。
        隐式调用指的是在创建对象的时候不写构造函数的参数列表,编译器会尝试调用对应参数的构造函数。

#include <iostream>
using namespace std;
class Student
{
private:int age;
public:explicit Student(int a):age(a){cout << "构造函数" << endl;}Student():age(1){cout << "无参构造函数" << endl;}int get_age(){return age;}
};
int main()
{Student s1(12); // 显式调用cout << s1.get_age() << endl;Student s3 = Student(14);   // 显式调用cout << s3.get_age() << endl;// Student s4 = 15;    // 隐式调用// cout << s4.get_age() << endl;Student* s2 = new Student(13);  // 显式调用cout << s2->get_age() << endl;Student s5;cout << s5.get_age() << endl;return 0;
}

建议使用显式调用,可以使用explict关键字屏蔽隐式调用语法。

拷贝构造函数

        当程序员不手写拷贝构造函数时,编译器会自动添加一个拷贝构造函数,使对象创建可以通过这个构造函数实现。

#include <iostream>
using namespace std;
class Student
{
private:int age;
public:Student(int a):age(a){cout << "构造函数" << endl;} Student(const Student &st){age = st.age;cout << "拷贝构造函数被调用了" << endl;}int get_age(){return age;}
};
int main()
{Student s1(12);cout << s1.get_age() << endl;Student s2(s1);     // 拷贝构造函数cout << s2.get_age() << endl;return 0;
}

拷贝构造函数存在隐患,当成员变量出现指针类型时,默认的拷贝构造函数会导致两个对象的成员变量指向同一处,不合符面向对象的设计规范,这种现象被称为“浅拷贝”。

浅拷贝
#include <iostream>
#include <string.h>
using namespace std;
class Dog
{
private:char *name;
public:Dog(char *n){name = n;}void show_name(){cout << name << endl;}
};
int main()
{char arr[20] = "旺财";Dog d1(arr);Dog d2(d1); // 拷贝构造函数strcpy(arr,"大黄");   // 更改外部内存,对象内部的数据也跟着进行更改,因为操作的同一块内存空间d1.show_name(); // 大黄d2.show_name(); // 大黄return 0;
}

这种情况必须手动重写构造函数,使每次赋值都创建一个新的副本,从而每个对象单独持有自己的成员变量,这种方式被称为“深拷贝”。

 深拷贝
#include <iostream>
#include <string.h>
using namespace std;
class Dog
{
private:char *name;
public:Dog(char *n){name = new char[20];strcpy(name,n);}Dog(Dog &d){name = new char[20];strcpy(name,d.name);}void show_name(){cout << name << endl;}
};
int main()
{char arr[20] = "旺财";Dog d1(arr);Dog d2(d1); // 拷贝构造函数strcpy(arr,"大黄");d1.show_name(); // 旺财d2.show_name(); // 旺财return 0;
}

在需求不受影响的情况下,可以通过屏蔽拷贝构造函数(私有化),来解决浅拷贝的问题。深拷贝的代码也存在隐患,new开辟的空间无法方便的进行释放,造成内存泄漏的问题。

补充:
1、添加无参构造函数,编译器还会添加默认无参构造函数嘛?(不会)
2、添加任意构造函数,编译器还会添加默认无参构造函数嘛?(不会)
3、添加无参构造函数,编译器还会添加默认拷贝构造函数嘛?(会)
4、添加拷贝构造函数,编译器还会添加默认拷贝构造函数嘛?(不会)

析构函数

析构函数是与构造函数对立的函数。

构造函数析构函数
创建对象时手动调用当对象销毁时,自动调用
函数名称是类名 函数名称是~类名
构造函数可以重载析构函数没有参数,不能重载
用于创建对象时并初始化用于销毁对象时释放资源
有返回值但是不写,返回值是新创建的对象  没有返回值
#include <iostream>
#include <string.h>
using namespace std;
class Dog
{
private:char *name;
public:Dog(char *n){name = new char[20];strcpy(name,n);}Dog(Dog &d){name = new char[20];strcpy(name,d.name);}void show_name(){cout << name << endl;}~Dog(){cout << "析构函数被调用了" << endl;delete []name;}
};
int main()
{char arr[20] = "旺财";Dog d1(arr);Dog d2(d1); // 拷贝构造函数strcpy(arr,"大黄");d1.show_name(); // 旺财d2.show_name(); // 旺财Dog *d3 = new Dog(arr);delete d3;  // 销毁时调用析构函数return 0;
}

作用域限定符:

名字空间

#include <iostream>
#include <string.h>
using namespace std;
namespace my_space// 名字空间
{int a = 3;int b = 4;
}
using namespace my_space;
int a = 2;
int main()
{
int a = 1;
cout << a << endl; // 就近原则,打印1
cout << ::a << endl; // ::全局作用域(匿名名字空间)2
cout << my_space::a << endl; // 3
cout << b << endl; // 4
return 0;
}

类内声明,类外定义

#include <iostream>
using namespace std;
class Demo
{
public:// 类内声明Demo();void test(string str);
};
// 类外定义
Demo::Demo()
{cout << "创建了一个对象" << endl;
}
void Demo::test(string str)
{cout << "string:" << str << endl;
}
int main()
{Demo d1;d1.test("hello");return 0;
}

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

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

相关文章

CentOS7搭建Hadoop3集群教程

一、集群环境说明 1、用VMware安装3台Centos7虚拟机 2、虚拟机配置&#xff1a;2C&#xff0c;2G内存&#xff0c;50G存储 3、集群架构设计 从表格中&#xff0c;可以看出&#xff0c;Hadoop集群&#xff0c;主要有2个模块服务&#xff0c;一个是HDFS服务&#xff0c;一个是YAR…

wordpress更换域名后用户图片头像不显示

&#x1f3c6;本文收录于《全栈Bug调优(实战版)》专栏&#xff0c;主要记录项目实战过程中所遇到的Bug或因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&am…

【Python报错已解决】AttributeError: ‘DataFrame‘ object has no attribute ‘append‘

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 专栏介绍 在软件开发和日常使用中&#xff0c;BUG是不可避免的。本专栏致力于为广大开发者和技术爱好者提供一个关于BUG解决的经…

基于深度学习的文本情感原因提取研究综述——论文阅读

前言 既然要学习情感分析&#xff0c;那么肯定还要了解情感原因对抽取的发展历程&#xff0c;所以我又搜了一篇研究综述&#xff0c;虽然是2023年发表的&#xff0c;但是里面提及到的历程仅停留到2022年。这篇综述发布在TASLP期刊&#xff0c;是音频、声学、语言信号处理的顶级…

【论文解读系列】用于自监督点云表示的生成变分对比学习

Generative Variational-Contrastive Learning for Self-Supervised Point Cloud Representation | IEEE Transactions on Pattern Analysis and Machine Intelligence (acm.org) 作者&#xff1a;Bohua Wang; Zhiqiang Tian; Aixue Ye; Feng Wen; Shaoyi Du; Yue Gao 摘要 三…

Coggle数据科学 | 科大讯飞AI大赛:玉米雄穗识别挑战赛

本文来源公众号“Coggle数据科学”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;科大讯飞AI大赛&#xff1a;玉米雄穗识别挑战赛 赛题名称&#xff1a;玉米雄穗识别挑战赛 赛题类型&#xff1a;计算机视觉、物体检测 赛题任务&…

LeetCode_sql_day30(1264.页面推荐)

描述 1264.页面推荐 朋友关系列表&#xff1a; Friendship ------------------------ | Column Name | Type | ------------------------ | user1_id | int | | user2_id | int | ------------------------ (user1_id, user2_id) 是这张表具有唯一值的…

HT326 免电感滤波2x20W D类立体声音频功放

特点 输出功率(BTL模式) 2x20W (VDD14.5V,RL4Ω,THDN1%) 单电源系统: 4.5V-18V; 超过90%效率&#xff0c;无需散热器 扩频功能&#xff0c;免电感滤波 模拟差分/单端输入可选 增益:32dB 保护功能:过压/过流/过热/欠压异常&#xff0c;直流检测 和短路保护 无铅无卤封装&#x…

Python画笔案例-054 绘制流光溢彩动画

1、绘制流光溢彩动画 通过 python 的turtle 库绘制 流光溢彩动画&#xff0c;如下图&#xff1a; 2、实现代码 绘制流光溢彩动画&#xff0c;以下为实现代码&#xff1a; """本程序实现流光溢彩的动画效果 """ from turtle import * from color…

流动网红打卡车!苏州金龙海格双层巴士带你体验别样津门津韵

近日&#xff0c;由文化和旅游部主办&#xff0c;天津市文化和旅游局等单位承办的2024中国文化旅游产业博览会在天津拉开帷幕&#xff0c;展会期间&#xff0c;来自全国各地的文旅产品精彩亮相。而在天津交通集团展台&#xff0c;来自苏州金龙海格客车制造的网红双层观光“音乐…

YOLOv8改进 - 注意力篇 - 引入ECA注意力机制

一、本文介绍 作为入门性第一篇&#xff0c;这里介绍了ECA注意力在YOLOv8中的使用。包含ECA原理分析&#xff0c;ECA的代码、ECA的使用方法、以及添加以后的yaml文件及运行记录。 二、ECA原理分析 ECA官方论文地址&#xff1a;ECA文章 ECA的pytorch版代码&#xff1a;ECA的…

Unet改进41:添加gConvBlock(2024最新改进方法)|

本文内容:在不同位置添加gConvBlock 目录 论文简介 1.步骤一 2.步骤二 3.步骤三 4.步骤四 论文简介 图像去雾是低层次视觉中的一个活跃话题,随着深度学习的快速发展,许多图像去雾网络被提出。尽管这些网络的管道运行良好,但改善图像去雾性能的关键机制仍不清楚。因此…

[Simpfun游戏云1]搭建MC Java+基岩互通生存游戏服务器

众所周知&#xff0c;MC有多个客户端&#xff0c;像常见的比如Java Edition和基岩等&#xff0c;这就导致&#xff0c;比如我知道一个超级好玩的JE服务器&#xff0c;但我又想使用基岩版来玩&#xff0c;肯定是不行的&#xff0c;因为通讯协议不一样。 这就有一些人才发明了多…

【linux】4张卡,坏了1张,怎么办?

先禁用这张卡 grub 禁用&#xff0c;防止加载驱动 禁用这张卡的 PCI # 禁用 PCI 设备 0000:b1:00.0 (NVIDIA GPU) ACTION"add", SUBSYSTEM"pci", ATTR{vendor}"0x10de", KERNELS"0000:b1:00.0", RUN"/bin/sh -c echo 0000:b1:00…

javaseday28 IO

IO流 IO流;存储和读取数据的解决方案。 纯文本文件&#xff1a;Windows自带的记事本打开能读懂的文件&#xff0c;word和Excel不是纯文本文件&#xff0c;txt和md是纯文本文件。 小结 IO流体系 FileOutputStream public class Demo1 {public static void main(String[] args)…

Ping32加密利器 vs ipguard,企业数据防护的实战对比

在数字化时代&#xff0c;企业数据的安全防护已成为不可忽视的重要议题。随着数据泄露事件的频发&#xff0c;企业迫切需要采用高效、可靠的数据防泄漏解决方案来保护其敏感信息。Ping32和IP-Guard作为市场上备受瞩目的两款数据保护工具&#xff0c;各自以其独特的功能和优势赢…

深入分析几个难以理解的Comparator源码

1.分析comparing单参数方法 网上很多帖子说实话&#xff0c;不咋地&#xff0c;讲的不细节&#xff0c;抄来抄去&#xff0c;就让我这个大二的垃圾&#xff0c;给大家梳理一下Comparator这几个难以理解public static方法吧。 1.1函数式接口Function 这个函数是使用的函数式编程…

OrCAD使用,快捷键,全选更改封装,导出PCB网表

1 模块名称 2 快捷键使用 H: 镜像水平 V&#xff1a;镜像垂直 R: 旋转 I: 放大 O&#xff1a; 放小 P&#xff1a;放置元器件 W&#xff1a; 步线 B&#xff1a; 总线&#xff08;无电气属性&#xff09; E: 总线连接符&#xff08;和BUS一起用&#xff09…

图的应用(关键路径)

基于你设计的带权有向无环图&#xff0c;写出所有合法的关键路径&#xff0c;并算出关键路径总长度 文字描述&#xff1a;关键路径总长度的现实意义是什么&#xff1f; 1.关键路径 总长度454316 2.现实意义 从源点到汇点的所有路径中&#xff0c;具有最大路径长度的路径称…

如何选择OS--Linux不同Distribution的选用

写在前言&#xff1a; 刚写了Windows PC的不同editions的选用&#xff0c;趁热&#xff0c;把Linux不同的Distribution选用也介绍下&#xff0c;希望童鞋们可以了解-->理解-->深入了解-->深入理解--...以致于能掌握特定版本的Linux的使用甚者精通。……^.^…… so&a…