C++(学习)2024.9.20
目录
C++面向对象的基础知识
this指针
概念
功能
1.类内调用成员
2.区分重名的成员变量和局部变量
3. 链式调用
static关键字
1.静态局部变量
2.静态成员变量
3.静态成员函数
4.单例设计模式
const关键字
1.const修饰成员函数
2.const修饰对象
3.const修饰成员变量
4.const修饰局部变量
运算符重载
友元
1.概念
2.友元函数
3.友元类
4.友元成员函数
C++面向对象的基础知识
this指针
概念
this指针是一个特殊的指针,指向当前类对象的首地址。
成员函数(包括构造函数和析构函数)中都有this指针,因此this指针只能在类内使用。实际上this指针指向的就是当前运行的成员函数所绑定的对象。
#include <iostream>
using namespace std;
class Test
{
public:void test_this(){cout << this << endl;}
};
int main()
{Test t1;cout << &t1 << endl;t1.test_this();Test t2;cout << &t2 << endl;t2.test_this();Test *t3 = new Test;cout << t3 << endl;t3->test_this();delete t3;return 0;
}
功能
1.类内调用成员
成员(成员变量+成员函数)必须由对象调用。类中成员的调用都依赖于this指针的,通常由编译器自动添加。
#include <iostream>
using namespace std;
class Test
{
private:string name;
public:Test(string n){this->name = n;}string get_name(){return this->name;}
};
int main()
{Test t1("zhangsan");cout << t1.get_name() << endl;return 0;
}
2.区分重名的成员变量和局部变量
#include <iostream>
using namespace std;
class Test
{
private:string name;
public:Test(string name){this->name = name; // 通过this指针在函数体中进行区分}string get_name(){return name;}
};
int main()
{Test t1("zhangsan");cout << t1.get_name() << endl;return 0;
}
3. 链式调用
支持链式调用的成员函数特点:
●当一个成员函数的返回值是当前类型的引用时,往往表示这个函数支持链式调用。
●return后面是*this。
#include <iostream>
using namespace std;
class Test
{
private:int val = 0;
public:Test &add(int i){val += i;return *this;}int get_val(){return val;}
};
int main()
{Test t1;t1.add(1);t1.add(2);t1.add(100);cout << t1.get_val() << endl; // 103// 链式调用Test t2;cout << t2.add(2).add(3).add(200).get_val() << endl;return 0;
}
static关键字
1.静态局部变量
使用static修饰局部变量,这样的变量就是静态局部变量。
静态局部变量在第一次调用时创建,直到程序结束后销毁,同一个类的所有对象共用这一份静态局部变量。
#include <iostream>
using namespace std;
class Test
{
public:void func(){int a = 1;static int b = 1;cout << "a=" << ++a << " " << &a << endl;cout << "b=" << ++b << " " << &b << endl;}
};
int main()
{Test t1;t1.func();t1.func();t1.func();Test t2;t2.func();Test *t3 = new Test;t3->func();return 0;
}
注意:a可能会在同一个内存地址反复创建销毁。
2.静态成员变量
使用static修饰成员变量,这样的变量就是静态成员变量。
需要在类内声明,类外初始化。
一个类的所有对象共用一份静态成员变量。虽然静态成员变量可以使用对象调用的,但是更建议直接使用类名调用。所以静态成员变量可以脱离对象使用,在程序开始运行时就开辟内存空间,程序执行结束后销毁。
更推荐使用类名直接调用,代码的可读性更高。
#include <iostream>
using namespace std;
class Test
{
public:int a = 1;static int b;
};
// 静态成员变量,类外初始化
int Test::b = 1;int main()
{cout << Test::b << &Test::b << endl;Test t1;cout << t1.a++ << &t1.a << endl;cout << t1.b++ << &t1.b << endl;cout << " --------------- " << endl;Test t2;cout << t2.a++ << &t2.a << endl;cout << t2.b++ << &t2.b << endl; return 0;
}
3.静态成员函数
使用static修饰成员函数,这样的函数就是静态成员函数。
与静态成员变量相似的有:
都可以通过类名直接调用,也可以通过对象进行调用,也可以脱离对象使用。
静态成员函数没有this指针,不能再静态成员函数中调用同类中其他非静态成员,但是静态成员函数可以调用静态成员。
#include <iostream>
using namespace std;
class Test
{
public:void func0(){//func1(); // 非静态成员函数可以调用静态成员函数cout << "非静态成员函数" << endl;}static void func1(Test &t){Test t2;t2.func0();t.func0();//func0(); // 错误 静态成员函数,不能调用非静态成员函数cout << "静态成员函数1" << endl;}
};int main()
{Test t1;Test t;t1.func1(t);return 0;
}
静态成员函数内调用当前类的非静态成员需要通过参数将对象传递进来,也可以在函数内创建对象进行调用。
4.单例设计模式
设计模式是一套被反复使用、多人知晓、经过分类的、代码设计经验的总结。通常用于一些面向对象的语言,如:JAVA、C++、C#等。这里以一个简化版本的单例设计模式为例,讲解static的实际使用。
#include <iostream>
using namespace std;
class Singleton
{
private:Singleton(){}Singleton(const Singleton&);static Singleton *instance; // 静态成员变量
public:static Singleton* get_instance() // 静态成员函数{if(instance == NULL){instance = new Singleton;}return instance;}static void delete_instance(){if(instance != NULL){delete instance;instance = NULL;}}
};
Singleton *Singleton::instance = NULL;
int main()
{Singleton *s1 = Singleton::get_instance();Singleton *s2 = Singleton::get_instance();cout << s1 << endl;cout << s2 << endl;return 0;
}
const关键字
1.const修饰成员函数
const修饰的成员函数,表示常成员函数。
特性:
(1)可以调用成员变量,但是不能修改成员变量的值
(2)不能调用非const的修饰的成员函数,哪怕这个函数并没有修改成员变量。
建议只要成员函数不修改成员变量就使用const修饰,例如show、get等等。
#include <iostream>
using namespace std;
class Demo
{
private:int a;
public:Demo(int a){this->a = a;}void func0(){cout << "hello" << endl;}int get_demo()const{return a;}void test()const // 常成员函数{//a++; // 错误 const修饰的成员函数,不能修改成员变量cout << a << endl;//func0(); // 错误,const修饰的成员函数,不能调用非const修饰的成员函数get_demo();}
};
int main()
{Demo demo(1);demo.test();cout << demo.get_demo() << endl;return 0;
}
2.const修饰对象
const修饰的对象被称为常量对象,这种对象的成员变量值无法被修改,也无法调用非const的成员函数。
#include <iostream>
using namespace std;
class Demo
{
private:int a;
public:int b = 20;Demo(int a){this->a = a;}void func0(){cout << "hello" << endl;}int get_demo()const{return a;}void test()const // 常成员函数{//a++; // 错误 const修饰的成员函数,不能修改成员变量cout << a << endl;//func0(); // 错误,const修饰的成员函数,不能调用非const修饰的成员函数get_demo();}};int main()
{const Demo demo(1); //Demo const demo(1);cout << demo.get_demo() << endl; //demo.func0(); // 错误,const修饰对象,无法调用非const修饰的成员函数demo.test();cout << demo.b << endl;//demo.b = 10; // 错误,const修饰的对象,无法修改成员变量return 0;
}
3.const修饰成员变量
const修饰的成员变量为常成员变量,表示该成员变量的值无法被修改。
常成员变量有两种初始化方式:
(1)声明后直接赋值
(2)构造初始化列表
上述两种方式同时使用时,以构造初始化列表为准。
#include <iostream>
using namespace std;
class Demo
{
private:const int a = 1;const int b = 2;const int c = 3;
public:Demo(int a,int b,int c):a(a),b(b),c(c){}void show(){cout << a << " " << b << " " << c << endl;}
};int main()
{Demo d1(10,20,30);d1.show();return 0;
}
4.const修饰局部变量
const修饰局部变量,表示该局部变量不可被修改。 这种方式常用于引用参数。
#include <iostream>
using namespace std;class Demo
{
private:const int a = 1;const int b = 2;const int c = 3;
public:Demo(int a,int b,int c):a(a),b(b),c(c){}void show(){cout << a << " " << b << " " << c << endl;}void test(const int &a1){a1++;const int d = 10;}
};int main()
{int a = 1;Demo d1(10,20,30);d1.show();d1.test(a);return 0;
}
运算符重载
友元
1.概念
类实现了数据的隐藏和封装,类的数据成员一般定义为私有成员,仅能通过类的成员函数才能读写。如果数据成员定义为公共的,则又破坏了封装性。但是再某些情况下,需要频繁的读写类的数据成员,特别是在对某些成员函数多次调用时,由于参数传递,类型检查和安全性检查都需要时间的开销,而影响程序的运行效率。
友元有三种实现方式:
1.友元函数
2.友元类
3.友元成员函数
友元在于提高程序的运行效率,但是,它破坏了类的封装性和隐藏性,是的非成员函数能够访问类的私有成员,导致程序维护性变差,因此使用友元要慎重。
2.友元函数
友元函数不属于任何一个类,是一个类外的函数,但是需要在类内进行“声明”。虽然友元函数不是类中的函数,但是却可以访问类中的所有成员(包括私有成员)
#include <iostream>
using namespace std;
class Test
{
private:int a;
public:Test(int i):a(i){}void show(){cout << a << " " << &a << endl;}// 友元函数,类内声明friend void and_test(Test &t);
};// 友元函数
void and_test(Test &t)
{cout << ++t.a << " " << &t.a << endl;
}int main()
{Test t1(1);and_test(t1);t1.show();return 0;
}
友元函数的使用注意以下几点:
1.友元函数没有this指针
2.友元函数的“声明”可以放置到类中的任何位置,不受权限修饰符的影响。
3.一个友元函数理论上可以访问多个类,只需要再各个类中分别“声明”。
3.友元类
当一个类成为了另一个类Test的朋友时,类Test的所有成员都可以被类B访问,此时类B就是类Test的友元类。
#include <iostream>
using namespace std;
class Test
{
private:int a;
public:Test(int i):a(i){}void show(){cout << a << " " << &a << endl;}// 友元类,类内声明friend class B;
};
class B
{
public:void and_test(Test &t){++t.a;cout << t.a << " " << &t.a << endl;}void and_test1(Test &t){cout << ++t.a << " " << &t.a << endl;}
};
int main()
{Test t1(1);B b;b.and_test(t1);b.and_test1(t1);t1.show();return 0;
}
友元类的使用需要注意以下几点:
1.友元关系不能被继承
2.友元关系不具有交换性(比如:类B声明为类Test的友元,类B可以访问类Test中的成员,但是类Test不能访问类B中的私有成员,如果需要访问,需要将类Test声明成类B的友元)
互为友元代码,需要类内声明,类外实现。
#include <iostream>
using namespace std;
class Cat;
class Test
{
private:int a;
public:Test(int i):a(i){}void test(Cat &c);friend class Cat;
};
class Cat
{
private:int b;
public:Cat(int i):b(i){}void test1(Test &t);friend class Test;
};
void Test::test(Cat &c)
{cout <<c.b<<endl;
}
void Cat::test1(Test &t)
{cout <<t.a++<<endl;
}
int main()
{Test t(44);Cat c(12);c.test1(t);return 0;
}
4.友元成员函数
使类B中的成员函数成为类Test的友元成员函数,这样类B的该成员函数就可以访问类Test的所有成员了。
#include <iostream>
using namespace std;// 第四步:声明被访问的类
class Test;
class B
{
public:// 第二步:声明友元成员函数(类内声明,类外实现)void and_test(Test &t);
};class Test
{
private:int a;
public:Test(int i):a(i){}void show(){cout << a << " " << &a << endl;}// 友元成员函数,第一步:确定友元成员函数的格式并声明friend void B::and_test(Test &t);
};// 第三步:类外定义友元成员函数
void B::and_test(Test &t)
{++t.a;cout << t.a << " " << &t.a << endl;
}int main()
{Test t1(1);B b;b.and_test(t1);t1.show();return 0;
}
相关文章:

C++(学习)2024.9.20
目录 C面向对象的基础知识 this指针 概念 功能 1.类内调用成员 2.区分重名的成员变量和局部变量 3. 链式调用 static关键字 1.静态局部变量 2.静态成员变量 3.静态成员函数 4.单例设计模式 const关键字 1.const修饰成员函数 2.const修饰对象 3.const修饰成员变量…...

让AI激发创作力:OpenAI分享5位专业作家利用ChatGPT写作的案例技巧
大家好,我是木易,一个持续关注AI领域的互联网技术产品经理,国内Top2本科,美国Top10 CS研究生,MBA。我坚信AI是普通人变强的“外挂”,专注于分享AI全维度知识,包括但不限于AI科普,AI工…...

UEFI EDK2框架学习 (一)
01 Shell界面打印 执行qemu指令后 qemu-system-x86_64 -drive ifpflash,formatraw,fileOVMF.fd -nographic -net none出现shell界面 02 在UEFI shell中创建APP 创建SimplestApp文件夹以及SimplestApp.c、SimplestApp.inf cd edk2 mkdir SimplestAppuuidgen // generate …...

基于 BERT 的自定义中文命名实体识别实现
基于 BERT 的自定义中文命名实体识别实现 在自然语言处理中,命名实体识别(Named Entity Recognition,NER)是一项重要的任务,旨在识别文本中的特定实体,如人名、地名、组织机构名等。本文将介绍如何使用 BERT 模型实现自定义中文命名实体识别,并提供详细的代码分析和解读…...

中秋节特别游戏:给玉兔投喂月饼
🖼️ 效果展示 📜 游戏背景 在中秋这个充满诗意的节日里,玉兔因为贪玩被赶下人间。在这个温柔的夜晚,我们希望通过一个小游戏,让玉兔感受到人间的温暖和关怀。🐰🌙 🎮 游戏设计 人…...

python pdf转word或excel
python pdf转word或excel 直接上源码 main import gradio as gr import pdf2docx as p2d import Pdf2Excel as p2e import utils.id.IdUtil as idUtildef convert_pdf_to(pdf_file, pdf_pwd, pdf_to_type):if pdf_to_type "docx":# Convert PDF to DOCXcv p2d.C…...

GNU链接器(LD):位置计数器(.)功能及实例解析
0 参考资料 GNU-LD-v2.30-中文手册.pdf GNU linker.pdf1 前言 一个完整的编译工具链应该包含以下4个部分: (1)编译器 (2)汇编器 (3)链接器 (4)lib库 在GNU工具链中&…...

学习记录:js算法(四十三):翻转二叉树
文章目录 翻转二叉树我的思路网上思路递归栈 总结 翻转二叉树 给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点 图一: 图二: 示例 1:(如图一) 输入:root [4,2,7,1…...

关于 SQL 的 JOIN 操作
关于 SQL 的 JOIN 操作 在关系型数据库中,数据通常分布在多个表中。为了进行有效的数据检索,我们需要从不同的表中组合数据,这时就需要使用 JOIN 操作。本文将深入探讨 SQL 中不同类型的 JOIN 及其用法,以帮助你在数据库查询中更…...

聊聊AUTOSAR:基于Vector MICROSAR的TC8测试开发方案
技术背景 车载以太网技术作为汽车智能化和网联化的重要组成部分,正逐步成为现代汽车网络架构的核心,已广泛应用于汽车诊断(如OBD)、ECU软件更新、智能座舱系统、高清摄像头环视泊车系统等多个领域。 在这个过程中,ET…...

ES6中迭代器与生成器知识浅析
ES5及以下版本对JS几种集合,要存取数据一般需要用循环语句来遍历,就要初始化一个或多个变量来记录每一次循环在数据集合中的位置或数据值。这里容易出现超出边界问题,造成程序出错。另外,对于多次循环也需要跟踪理清各个变量关系及…...

unix中的vfork函数
一、前言 本文介绍unix中的vfork函数,vfork函数功能和fork函数类似,也是用于创建新的进程,只不过调用vfork函数创建的子进程将共享父进程的进程空间,且只有当子进程调用exec()或者exit()函数后,父进程才会继续运行。 …...

Android 用线程池实现一个简单的任务队列(Kotlin)
关于线程池,Kotlin和java的使用方式一样 在Android中,很多人喜欢用Handler的postDelayed() 去实现延时任务. 要使用postDelayed(),去实现延时任务队列,就不可避免要使用递归. 但是这样做,代码的简洁性,和书写的简易,就远不如使用线程池. 使用线程池的简单程度: private val…...

遨游信息技术的浩瀚宇宙:探索MySQL的深邃奥秘
遨游信息技术的浩瀚宇宙:探索MySQL的深邃奥秘 在信息技术的浩瀚宇宙中,MySQL犹如一颗璀璨的星辰,以其稳定、高效、灵活的特性,照亮了无数开发者与数据管理者的前行之路。作为关系型数据库管理系统的佼佼者,MySQL不仅承…...

【Bug解决】Nacos启动成功,但却无法访问(提示:无法访问此网站,192.168.10.88的响应时间过长)
项目场景: 在虚拟机上通过Docker创建Nacos容器,已经创建成功,查看Nacos启动日志也是成功。但通过端口号加8848/nacos(如:http://IP:8848/nacos)无法访问到Nacos管理页面。 愿意分析一: 先检查好…...

【AI创作组】工程方向的硕士研究生学习Matlab的路径
1. MATLAB软件概述 1.1 MATLAB发展历程 MATLAB自20世纪70年代诞生以来,已经经历了多次重要的版本更新和功能扩展。 初始版本:MATLAB的前身只是一个简单的交互式矩阵计算器,由Cleve B. Moler博士在1970年代初期开发,目的是为了方便学生和研究人员使用线性代数软件包LINPAC…...

Mac使用Nginx设置代理,并禁用自带Apache
Mac自带Apache服务,并占用80端口,如果需要使用Nginx,需要禁用Apache并自己安装Nginx 一、禁用自带Apache 1.关闭Apache sudo apachectl -k stop 如果出现如下报错:httpd: Could not reliably determine the server’s fully q…...

AlmaLinux 安裝JDK8
在 AlmaLinux 上安装 JDK 8 可以通过包管理器 dnf 来完成。AlmaLinux 是基于 RHEL 的一个开源发行版,因此其包管理系统和 RHEL 类似。以下是详细的步骤来安装 OpenJDK 8 1. 更新系统包列表 sudo dnf update -y 2. 安装 OpenJDK 8 使用 dnf 安装 OpenJDK 8。你可…...

Set 和 Map 的模拟实现
1、引言 在数据结构与算法的学习与实践中,关联容器(associative containers)是不可忽视的重要工具。作为高效管理数据的一类容器,C 标准库中的 set 和 map 在现代软件开发中扮演着关键角色。这两个容器通过平衡二叉搜索树&#x…...

深度学习自编码器 - 预测稀疏分解(PSD)篇
序言 在数据科学与机器学习的广阔领域中,深度学习作为一股不可忽视的力量,正引领着技术革新的浪潮。其中,自编码器( Autoencoder \text{Autoencoder} Autoencoder)作为一种特殊的神经网络结构,以其独特的自…...

如何检测出来这个ip是共享ip不安全
检测一个IP是否为共享IP以及其安全性可以通过以下几种方法和工具来进行分析。共享IP通常是指多个用户共享一个IP地址,常见于公共代理服务器、VPN服务或数据中心IP。如果你想评估一个IP是否为共享IP以及其安全性,以下方法和工具可以帮助你进行检测和分析。…...

TMStarget学习——T1 Segmentation数据处理及解bug
最新学习季公俊老师的神器 TMStarget 的第一个模块基于结构像的靶区计算T1 segmentation。下面上步骤: (1)在github 上下载 TMStarget https://github.com/jigongjun/Neuroimaging-and-Neuromodulation (2)按照要求下载依赖工具软件AFQ、vistasoft、SPM12 &#…...

锁策略, cas 和 synchronized 优化过程
1.1 常見的鎖策略 預測鎖衝突概率 樂觀鎖:加鎖的時候,假設出現鎖衝突的概率不大。圍繞加鎖做的工作會更少。 悲觀鎖:加鎖的時候,假設鎖出現衝突的概率很大。圍繞加鎖做的工作會更多。 synchronized “自適應” 初始是樂觀的。鎖…...

【HTML5】html5开篇基础(2)
1.❤️❤️前言~🥳🎉🎉🎉 Hello, Hello~ 亲爱的朋友们👋👋,这里是E绵绵呀✍️✍️。 如果你喜欢这篇文章,请别吝啬你的点赞❤️❤️和收藏📖📖。如果你对我的…...

大数据新视界 --大数据大厂之 Reactjs 在大数据应用开发中的优势与实践
💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…...

【论文阅读笔记】TOOD: Task-aligned One-stage Object Detection
论文代码:https://github.com/fcjian/TOOD 文章目录 论文小结论文简介论文方法Task-aligned Head(T-Head)T-Head伪代码解释 Task Alignment Learning(TAL)Task-aligned Sample AssignmentTask-aligned Loss 论文实验消…...

类中的特殊内容
仿照string类,自己手动实现 My_string #include <iostream> #include <string.h> using namespace std;class My_string { private:int len;int size;char *ptr; public:My_string():size(15),len(0){ptrnew char[size];ptr[0]\0;}My_string(const char…...

network request to https://registry.npmjs.org/xxx failed, reason: connect ETIM
目录: 1、问题描述2、解决方案3、npm镜像仓库替换 1、问题描述 npm install 时,报错:npm ERR! network request to https://registry.npmjs.org/postcss-pxtorem failed, reason: connect ETIMEDOU npm ERR! code ETIMEDOUT npm ERR! errno…...

MQ入门(二):java客户端SpringAMQP
目录 1.SpringAMQP 1.1.导入demo工程 1.2.快速入门 1.2.1.消息发送 1.2.2.消息接收 1.2.3.测试 1.3.WorkQueues模型 1.4.交换机类型 1.4.1.Fanout交换机 1.4.2.Direct交换机 1.4.3.Topic交换机 1.5.声明队列和交换机 1.5.1.基于注解声明 1.6.消息转换器 1.6.1.测…...

软技能与AI技术的融合
一、引言 ---- 随着人工智能(AI)和生成式人工智能(AIGC)如ChatGPT、Midjourney、Claude等大语言模型的迅速崛起,AI辅助编程工具已经变得越来越普遍。这不仅意味着程序员的工作方式正在发生深刻的变革,同…...