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;
}

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

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

相关文章

全视通解读政策风向,智慧手术室究竟怎么做信息化?

尽管智慧手术室的建设与发展日益重要&#xff0c;但是目前国内外对智慧手术室的定义仍是众说纷纭&#xff0c;直至日前&#xff0c;上海交通大学医学院附属瑞金医院、上海市数字医学创新中心联合L.E.K.咨询发布的《中国智慧手术室发展与实践白皮书》&#xff08;后简称《白皮书…

序列化方式二——JSON之fastjson

fastjson&fastjson2(版本&#xff1a;1.2.83_noneautotype) 扩展点 Fastjson通过其丰富的扩展点显著增强了用户定制序列化和反序列化行为的灵活性&#xff0c;完美契合了实际开发中的多样化需求。在SpringBoot与SpringCloud的集成环境中&#xff0c;开发者能够利用Seriali…

五、 共射极放大电路

共射极放大电路 1、三极管的结构、三极管各极电流关系、特性曲线、放大条件。   2、元器件的作用、电路的用途、电压放大倍数、输入和输出的信号电压相位关系、交流和直流等效电路图。 3、静态工作点的计算、电压放大倍数的计算。

【PCL实现点云分割】ROS深度相机实践指南(上):PCL库初识和ROS-PCL数据类型转换

前言 本教程使用PCL对ROS深度相机捕获到的画面进行操场上锥桶的分割 本人相关的RGBD深度相机原理及其使用教程&#xff1a; [csdn 博客] 上手一个RGBD深度相机&#xff1a;从原理到实践–ROS noeticAstra S&#xff08;上&#xff09;&#xff1a;解读深度测距原理和内外参推导…

金属3D打印经济效益高吗?

在我国制造业迈向产业升级的重要阶段&#xff0c;3D打印技术如同一股强劲的新风&#xff0c;特别是在航空航天、汽车、生物医疗等领域&#xff0c;已成为复杂构件制造的“明星”技术。那么&#xff0c;对于众多生产厂家而言&#xff0c;金属3D打印的经济账到底怎么算&#xff1…

rabbitmq 短信验证码

1.生成的验证码用redis存 减少数据库压力 2.通知运营商发送短信的事情交给rabbitmq的队列去做&#xff0c;无论成功或者是失败&#xff0c;用户那边都不知道。没有收到验证码&#xff08;监听失败&#xff09;用户只会觉得是运营商的问题&#xff0c;而不会怀疑是我们的系统有问…

深入掌握 Go 单元测试:从基础到进阶的完整指南

你好&#xff0c;我是陈明勇&#xff0c;一名热爱技术、乐于分享的开发者&#xff0c;同时也是开源爱好者。 成功的路上并不拥挤&#xff0c;有没有兴趣结个伴&#xff1f; 个人网站&#xff1a;https://chenmingyong.cn 文章持续更新&#xff0c;如果本文能让您有所收获&#…

罗马数字详解

一. 罗马数字の背景 1. 罗马数字的诞生与进化 罗马数字起源于古罗马帝国&#xff0c;拥有一个漫长而复杂的历史&#xff0c;始于公元前 8 世纪至 9 世纪&#xff0c;与古罗马帝国在帕兰丁山&#xff08;Palantine Hill&#xff09;周围建立的时间大致相同。不过&#xff0c;罗…

铲屎官进!宠物空气净化器真的有用吗?哪款去浮毛效果好

国庆小长假就要来了&#xff0c;别人都在苦恼抢票问题&#xff0c;而我在想会不会被我妈赶出家门... 毕业后我就留在了广州上班&#xff0c;独自一人租房难免会感觉孤独&#xff0c;就养了一只小猫和我作伴。这次放假这么久&#xff0c;我不放心留它一个人在家&#xff0c;也没…

SpringBoot 项目如何使用 pageHelper 做分页处理 (含两种依赖方式)

分页是常见大型项目都需要的一个功能&#xff0c;PageHelper是一个非常流行的MyBatis分页插件&#xff0c;它支持多数据库分页&#xff0c;无需修改SQL语句即可实现分页功能。 本文在最后展示了两种依赖验证的结果。 文章目录 一、第一种依赖方式二、第二种依赖方式三、创建数…

Virtuoso服务在centos中自动停止的原因分析及解决方案

目录 前言1. 问题背景2. 原因分析2.1 终端关闭导致信号12.2 nohup命令的局限性 3. 解决方案3.1 使用 screen 命令保持会话3.2 使用 tmux 作为替代方案3.3 使用系统服务&#xff08;systemd&#xff09; 4. 其他注意事项4.1 网络配置4.2 日志监控 结语 前言 在使用Virtuoso作为…

Transformer 的可视化解释

Transformer 的可视化解释&#xff1a;了解 LLM Transformer 模型如何与交互式可视化配合使用 部署 Nodejs version > 20.0 git clone https://github.com/poloclub/transformer-explainer.git cd transformer-explainer npm install npm run dev# fix: cnpm install --pl…

AD9854 为什么输出波形幅度受限??

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

lambda 自调用递归

从前序与中序遍历序列构造二叉树 官方解析实在是记不住&#xff0c;翻别人的题解发现了一个有意思的写法 class Solution { public:TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {auto dfs [](auto&& dfs, auto&&…

Pandas和matplotlib实现同期天气温度对比

目录 1、下载近两年的天气Excel数据 2、pandas加载Excel 3、将时间作为索引 4、按日计算最值、均值 5、选取近两年同期温度数据 6、同期温度曲线对比,共享y轴 1、下载近两年的天气Excel数据 一个免费的天气数据下载网址:METAR北京(机场)历史天气 (rp5.ru) 选择”北京天…

centos 7.9安装k8s

前言 Kubernetes单词来自于希腊语&#xff0c;含义是领航员&#xff0c;生产环境级别的容器编排技术&#xff0c;可实现容器的自动部署扩容以及管理。Kubernetes也称为K8S&#xff0c;其中8代表中间8个字符&#xff0c;是Google在2014年的开源的一个容器编排引擎技术&#xff…

一文读懂SpringCLoud

一、前言 只有光头才能变强 认识我的朋友可能都知道我这阵子去实习啦&#xff0c;去的公司说是用SpringCloud(但我觉得使用的力度并不大啊~~)… 所以&#xff0c;这篇主要来讲讲SpringCloud的一些基础的知识。(我就是现学现卖了&#xff0c;主要当做我学习SpringCloud的笔记吧&…

【JPCS出版】第二届应用统计、建模与先进算法国际学术会议(ASMA2024,9月27日-29)

第二届应用统计、建模与先进算法国际学术会议 2024 2nd International Conference on Applied Statistics, Modeling and Advanced Algorithms&#xff08;ASMA2024&#xff09; 会议官方 会议官网&#xff1a;www.icasma.org 2024 2nd International Conference on Applied …

Moveit2与gazebo联合仿真:添加摄像头传感器

1.代码更新修改 1.1 添加物理关节 如图&#xff0c;在原有机械臂的基础上添加camera_link和base_camera_joint作为传感器的几何属性 对应的xml代码如下 <link name"${prefix}camera_link"><collision><geometry><box size"0.01 0.1 0.05&…

【Python】练习:控制语句(二)第4关

第4关&#xff1a;控制结构综合实训 第一题第二题&#xff08;※&#xff09;第三题&#xff08;※&#xff09;第四题&#xff08;※&#xff09;第五题&#xff08;※&#xff09;第六题&#xff08;※&#xff09; 第一题 #第一题def rankHurricane(velocity):#请在下面编写…