C++高级语法
文章目录
- C++高级语法
- 面向对象 -- 类/结构体
- 抽象-具体类型
- 标准I/O流
- I/O流
- I/O缓存区
- 文件操作
- 头文件的重复包含问题
- 深拷贝和浅拷贝,写时复制
- 面向对象的三大特性
- 面向对象是什么
C++高级语法
面向对象 – 类/结构体
- C++使用class定义一个类,使用struct定义一个结构体
struct的默认成员权限是public,class的默认成员权限是private,除此之外二者基本没有差别。
抽象-具体类型
- 让自定义类型的类像内置类型一样
封装和函数重载示例:
Complex.h
#include <iostream>
using namespace std;class Complex
{
public:Complex(); // 默认构造函数Complex(double r, double i); // 构造函数virtual ~Complex(); // 析构函数Complex(const Complex& x); // 拷贝构造Complex& operator=(const Complex &c); // =号运算符double GetReal( ) const { return _real; }void SetReal(double d) { _real = d; }double GetImage() const { return _image; }void SetImage(double i) { _image = i; }// 运算符重载Complex operator+(const Complex &c) const;Complex& operator+=(const Complex &c);Complex operator-(const Complex &c) const;Complex& operator-=(const Complex &c);Complex operator*(const Complex &c) const;Complex& operator*=(const Complex &c);Complex operator/(const Complex &c) const;Complex& operator/=(const Complex &c);bool operator==(const Complex &c) const;bool operator!=(const Complex &c) const;bool operator>(const Complex &c) const;bool operator>=(const Complex &c) const;bool operator<(const Complex &c) const;bool operator<=(const Complex &c) const;// 前置和后置++Complex& operator++(); //前置++Complex operator++(int); //后置++Complex& operator--(); //前置--Complex operator--(int); //后置--//protected:friend ostream& operator<<(ostream& os, const Complex &x);friend istream& operator>>(istream& is, Complex &x);private:double _real; // 复数的实部double _image; // 复数的虚部
};
Complex.cpp
#include "Complex.h"Complex::Complex()
{_real = 0.0;_image = 0.0;//cout << "Complex::Complex()" << endl;
}Complex::Complex(double r, double i)
{_real = r;_image = i;//cout << "Complex::Complex(double r, double i)" << endl;
}Complex::Complex(const Complex& c)
{_real = c._real;_image = c._image;//cout << "Complex::Complex(const Complex& c)" << endl;
}Complex& Complex::operator= (const Complex& c)
{if (this != &c){_real = c._real;_image = c._image;}return *this;
}Complex::~Complex()
{_real = _image = 0.0;//cout << "Complex::~Complex()" << endl;
}Complex Complex::operator+ (const Complex& c) const
{//Complex tmp;//tmp._real = _real + x._real;//tmp._image = _image + x._image;//return tmp;return Complex(_real + c._real, _image + c._image);
}Complex& Complex::operator+= (const Complex& c)
{_real += c._real;_image += c._image;return *this;
}Complex Complex::operator-(const Complex &c) const
{return Complex(_real - c._real, _image - c._image);
}Complex& Complex::operator-=(const Complex &c)
{_real -= c._real;_image -= c._image;return *this;
}Complex Complex::operator*(const Complex &c) const
{return Complex(_real*c._real - _image*c._image, _real*c._image + _image*c._real);
}Complex& Complex::operator*=(const Complex &c)
{Complex tmp(*this); //拷贝构造函数_real = tmp._real*c._real - _image*c._image;_image = tmp._real*c._image + tmp._image*c._real;return *this;
}Complex Complex::operator/(const Complex &c) const
{double t = c._real*c._real + c._image*c._image;return Complex((_real*c._real - _image*(-c._image)) / t, (_real*(-c._image) + _image*c._real) / t);
}Complex& Complex::operator/=(const Complex &c)
{Complex tmp(*this); //拷贝构造函数double t = c._real*c._real + c._image*c._image;_real = (tmp._real*c._real - tmp._image*(-c._image)) / t;_image = (tmp._real*(-c._image) + tmp._image*c._real) / t;return *this;
}bool Complex::operator==(const Complex& c) const
{return (_real == c._real) && (_image == c._image);
}bool Complex::operator!=(const Complex& c) const
{return !( (_real == c._real) && (_image == c._image) );
}bool Complex::operator>(const Complex &c) const
{return (_real > c._real) && (_image > c._image);
}bool Complex::operator>=(const Complex &c) const
{return (_real >= c._real) && (_image >= c._image);
}bool Complex::operator<(const Complex &c) const
{return (_real < c._real) && (_image < c._image);
}bool Complex::operator<=(const Complex &c) const
{return (_real <= c._real) && (_image <= c._image);
}Complex& Complex::operator++ () // 前置++
{_real++;_image++;return *this;
}Complex Complex::operator++ (int) // 后置++
{//Complex tmp(*this);//_real++;//_image++;//return tmp;return Complex(_real++, _image++);
}Complex& Complex::operator--() //前置--
{_real--;_image--;return *this;
}Complex Complex::operator--(int) //后置--
{return Complex(_real--, _image--);
}ostream& operator<<(ostream& os, const Complex &x)
{os << "real value is " << x._real << " image value is " << x._image;return os;
}istream& operator >> (istream& is, Complex &x)
{is >> x._real >> x._image;return is;
}
标准I/O流
I/O流
-
传统C中的I/O流有printf,scanf,getch,gets等函数:他们的问题是:
- 不可编程,仅仅能识别固有数据类型
1. 代码可移植性差,有很多坑
- 不可编程,仅仅能识别固有数据类型
-
C++中的I/O流istream,ostream等:
- 可编程,对于使用类库的设计者来说很有用
- 简化编程,使得I/O风格一致
I/O缓存区
- 标准IO提供三种类型的缓存模式
- 按块缓存:如文件系统
- 按行缓存:\n
- 不缓存。
文件操作
- 输入流的七点和输出流的终点都可以是磁盘文件
- 文件:C++把每个文件都看成是一个有序的字节序列,每个文件都是以文件结束标志结束
- 按照文件中的数据的组织形式可以把文件分成:
- 文本文件:文件中信息形式为ASCII码文件,每个字符占一个字节
- 二进制文件:文件中信息的形式与其在内存中的形式相同
文件操作步骤:
- 打开文件用于读和写 open;
- 检查是否打开成功 fail;
- 读或者写操作;
- 检查是否读完EOF;
- 使用完成之后关闭文件;
文件的打开方式:
方式 | 描述 |
---|---|
ios::in | 打开文件进行读操作 |
ios::out | 打开文件进行写操作 |
ios::ate | 打开一个已有输入或者输出文件并查找文件结尾 |
ios::app | 打开文件以便在文件尾部添加数据 |
ios::nocreate | 如果文件不存在则打开失败 |
ios::trunc | 如果文件存在,清除文件内容 |
ios::binary | 以二进制形式打开 |
#include <string>
#include <fstream>
#include <iostream>
using namespace std;static const int bufferLen = 2048;
bool CopyFile(const string& src, const string& dst)
{// 打开源文件和目标文件// 源文件以二进制读的方式打开// 目标文件以二进制写的方式打开ifstream in(src.c_str(), ios::in | ios::binary);ofstream out(dst.c_str(), ios::out | ios::binary | ios::trunc);// 判断文件打开是否成功,失败返回falseif (!in || !out){return false;}// 从源文件中读取数据,写到目标文件中// 通过读取源文件的EOF来判断读写是否结束char temp[bufferLen];while (!in.eof()){in.read(temp, bufferLen);streamsize count = in.gcount();out.write(temp, count);}// 关闭源文件和目标文件in.close();out.close();return true;
}int main()
{cout << CopyFile("Blue Daube.mp3", "Blue Daube2.mp3") << endl;//int a;//int index = 0;//fstream fout;//fout.open("testBuffer.txt", ios::app);if (fout.fail())//if (!fout)//{// cout << "open file failed" << endl;//}//while (cin >> a)//{// //cout << "The numbers are: " << a << endl;// fout << "The numbers are: " << a << endl;// index++;// if (index == 5)// {// break;// }//}//cin.ignore(numeric_limits<std::streamsize>::max(), '\n'); // 清空缓存区脏数据//char ch;//cin >> ch;cout << "the last char is: " << ch << endl;//fout << "the last char is: " << ch << endl;//fout.close();return 0;
}
头文件的重复包含问题
-
为了避免同一个文件被多次include ,有两种方式
-
#ifndef aa #define aa #endif
使用宏来方式同一个文件被多次包含
优点:可移植性好
缺点:无法防止宏名称重复,难以排查错误
-
#program once
使用编译器来防止同一个文件被多次包含
优点:可以防止宏名重复,易排错
缺点:可移植性不好
-
深拷贝和浅拷贝,写时复制
- 浅拷贝:只拷贝指针地址,C++默认拷贝构造函数与赋值运算符都是浅拷贝,节省空间,但是容易引发多次释放;
- 深拷贝:重新分配堆内存,拷贝指针指向内容。浪费空间,但不会导致多次释放;
如何同时具备二者的优点?
- 使用引用计数
- C++新标准的移动语义
String.h
#pragma once
class String
{
public:String(const char *str = NULL); // 普通构造函数String(const String &other); // 拷贝构造函数String(String&& other); // 移动构造函数~String(void); // 析构函数String& operator= (const String& other); // 赋值函数String& operator=(String&& rhs)noexcept; // 移动赋值运算符friend ostream& operator<<(ostream& os, const String &c); // cout输出private:char *m_data; // 用于保存字符串
};
String.cpp
#include "stdafx.h"// _CRT_SECURE_NO_WARNINGS// String 的普通构造函数
String::String(const char *str)
{if (str == NULL){m_data = new char[1];if (m_data != NULL){*m_data = '\0';}else{exit(-1);}}else{int len = strlen(str);m_data = new char[len + 1];if (m_data != NULL){strcpy(m_data, str);}else{exit(-1);}}
}// 拷贝构造函数
String::String(const String &other)
{int len = strlen(other.m_data);m_data = new char[len + 1];if (m_data != NULL){strcpy(m_data, other.m_data);}else{exit(-1);}
}// 移动构造函数
String::String(String&& other)
{if (other.m_data != NULL){// 资源让渡m_data = other.m_data;other.m_data = NULL;}
}// 赋值函数
String& String::operator= (const String &other)
{if (this == &other){return *this;}// 释放原有的内容delete[ ] m_data;// 重新分配资源并赋值int len = strlen(other.m_data);m_data = new char[len + 1];if (m_data != NULL){strcpy(m_data, other.m_data);}else{exit(-1);}return *this;
}// 移动赋值运算符
String& String::operator=(String&& rhs)noexcept
{if(this != &rhs){delete[] m_data;m_data = rhs.m_data;rhs.m_data = NULL;}return *this;
}// String 的析构函数
String::~String(void)
{if (m_data != NULL){delete[] m_data;}
}ostream& operator<<(ostream& os, const String &c)
{os << c.m_data;return os;
}
main.cpp
int main()
{String s1("Hello"); // 构造函数cout << s1 << endl;//String s2 = s1; // 调用拷贝构造函数String s2(s1); // 调用拷贝构造函数cout << s2 << endl;String s2A(std::move(s1)); // 移动构造函数cout << s2A << endl;String s3; // 无参构造函数cout << s3 << endl;s3 = s2; // 调用赋值函数cout << s3 << endl;String s3A; // 无参构造函数s3A = std::move(s2A); // 移动赋值运算符cout << s3A << endl;return 0;
}
面向对象的三大特性
- 封装性:数据和代码捆绑在一起,避免外界干扰和不确定性访问,封装可以使得代码模块化
- 继承性:让某种类型对象获得另一个类型对象的属性和方法,继承可以扩展已存在的代码
- 多态性:同一事物表现出不同事物的能力,即面向不同的对象产生不同的行为,多态的目的是为了接口重用
面向对象是什么
- 面向对象是软件工程发展到一定的阶段为了管理代码和数据提出的一种方法,它没有解决以前解决不了的问题,不是万能的
- 面向对象不是对现实世界的映射,但他的封装性可以把问题简化,便于抽象;它的多台可以减少代码重复,避免重新发明轮子;它的多台可以实现灵活的功能扩展,提升开发效率
- 面向对象为我们便捷开发出能适应软件变化的软件提供了可能
相关文章:
C++高级语法
文章目录 C高级语法面向对象 -- 类/结构体抽象-具体类型 标准I/O流I/O流I/O缓存区 文件操作头文件的重复包含问题深拷贝和浅拷贝,写时复制面向对象的三大特性面向对象是什么 C高级语法 面向对象 – 类/结构体 C使用class定义一个类,使用struct定义一个…...

React学习笔记九-高阶函数与函数柯里化
此文章是本人在学习React的时候,写下的学习笔记,在此纪录和分享。此为第九篇,主要介绍高阶函数与函数柯里化。 高阶函数,和函数的柯里化,是学习react的拓展,方便以后优化代码,更好的学习react。…...

2023年电工杯B题半成品论文使用讲解
注:蓝色字体为说明备注解释字体,不能出现在大家的论文里。黑色字体为论文部分,大家可以根据红色字体的注记进行摘抄。该文件为半成品论文,即引导大家每一步做什么,怎么做,展示按着本团队的解题思路进行建模…...

第1关:ODBC程序设计
第1关:ODBC程序设计 任务描述相关知识ODBC主要功能ODBC接口主要函数ODBC应用程序开发实例DM ODBC应用程序开发总体流程DM ODBC代码编写流程DM ODBC代码编写实例 编程要求测试说明代码参考: 任务描述 本关任务:使用 ODBC 查询表中数据。 相关…...

Kotlin笔记(零)简介
百度百科简介 2017年,google公司在官网上宣布Kotlin成为Android的开发语言,使编码效率大增。Kotlin 语言由 JetBrains 公司推出,这是一个面向JVM的新语言 参考资料 官网:https://kotlinlang.org/中文官网:https://w…...
android 12.0去掉usb授权提示框 默认给予权限
1.概述 在12.0的系统rom产品开发中,在进行iot开发过程中,在插入usb设备时会弹出usb授权提示框,也带来一些不便,这个需要默认授予USB权限,插拔usb都不弹出usb弹窗所以这要从usb授权相关管理页默认给与usb权限 2.去掉usb授权提示框 默认给予权限的相关代码 frameworks/bas…...

工作积极主动分享,善于业务沟通
工作积极主动分享,善于业务沟通 目录概述需求: 设计思路实现思路分析1.工作积极主动承担责任2.善于沟通3.一起常常lauch 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy,…...
Opencv-C++笔记 (1) : opencv的数据结构
文章目录 一、OPNECV元素1.CvPoint2、模板类Size模版类Rect模版类RotatedRect模版类 二、MAT1.使用(nrows, ncols, type),初始化2维矩阵如果需要深拷贝,则使用clone方法。 三、Vec类 一、OPNECV元素 1.CvPoint 为了方便使用,opencv又对常用的…...

什么是时间复杂度?
时间复杂度定义:在计算机科学中,时间复杂性,又称时间复杂度,算法的时间复杂度是一个函数,它定性描述该算法的运行时间。这是一个代表算法输入值的的长度的函数。时间复杂度常用大O符号表述,不包括这个函数的…...

Spring框架中有哪些不同类型的事件
Spring框架中有哪些不同类型的事件 Spring框架中有哪些不同类型的事件 Spring框架中有哪些不同类型的事件 Spring 提供了以下5种标准的事件: 上下文更新事件(ContextRefreshedEvent):在调用ConfigurableApplicationContext 接口…...
Codeforcs 1732C2 暴力
题意 传送门 Codeforcs 1732C2 题解 方便起见,区间表示为左闭右开。观察到 f ( l , r ) ≥ f ( l ′ , r ′ ) , [ l ′ , r ′ ) ∈ [ l , r ) f(l,r)\geq f(l,r),[l,r)\in [l,r) f(l,r)≥f(l′,r′),[l′,r′)∈[l,r),满足单调性,则 […...

Python安全和防护:如何保护Python应用程序和用户数据的安全
章节一:引言 在当今数字化时代,数据安全是一个极其重要的话题。随着Python的广泛应用和越来越多的人使用Python构建应用程序,保护Python应用程序和用户数据的安全变得尤为重要。本文将介绍一些关键的Python安全问题,并提供一些保…...

[转载]Nginx 使用 X-Accel-Redirect 实现静态文件下载的统计、鉴权、防盗链、限速等
需求 统计静态文件的下载次数;判断用户是否有下载权限;根据用户指定下载速度;根据Referer判断是否需要防盗链;根据用户属性限制下载速度; X-Accel-Redirect This allows you to handle authentication, logging or …...
继电器的详细分类
继电器的分类方法较多,可以按作用原理、外形尺寸、保护特征、触点负载、产品用途等分类。 一、按作用原理分 1.电磁继电器 在输入电路内电流的作用下,由机械部件的相对运动产生预定响应的一种继电器。 它包括直流电磁继电器、交流电磁继电器、…...

docker的底层原理,带你上天
1、docker的层级怎么看 先查看当前机器上有哪些镜像 docker images 这里选看mysql的层级 docker image inspect mysql:5.7.29 命令。其中RootFS部分则是表示了分层信息。 2、查看docker的系统信息 因为这台机器的docker不是我安装的,所以不知道具体的根目录在哪里…...

HNU-电子测试平台与工具2-串口实验5次
计算机串口使用与测量 【实验属于电子测试平台与工具】 湖南大学信息科学与工程学院 计科 210X wolf (学号 202108010XXX) 0.环境搭建 在实验开始之前,安装好Ubuntu 20.04操作系统。(这个没有难度) 但要提醒的是,这个ubuntu是xubuntu,而且虚拟硬盘只有10GB的大小…...

Ext JS嵌套分组表格的实现
这里的嵌套分组表格指的是这样一种表格 表格的每一行可以展开下一层的Grid展开的嵌套表格是一个分组的表格显示的效果如下图: 这种显示的方式可以显示 3个层级的数据,比如这里的国家 、 将军等级、将军信息。 如果最外层再使用分组的表格, 则可以显示 4个层级的信息, 这种…...

【配电网重构】基于改进二进制粒子群算法的配电网重构研究(Matlab代码实现
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
Python编程语言简介
Python 是荷兰人 Guido van Rossum (吉多范罗苏姆,中国程序员称其为“龟叔”)在 1990 年初开发的一种解释型编程语言。 Python 的诞生是极具戏曲性的,据 Guido 自述记载,Python 语言是在圣诞节期间为了打发无聊的时间…...

ChatGPT国内免费访问
背景 ChatGPT作为一种基于人工智能技术的自然语言处理工具,近期的热度直接沸腾🌋。 作为一个程序员,我也忍不住做了一个基于ChatGPT的网站,免费!免梯子!!国内可直接对话ChatGPT,也…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...

STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...
MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用
文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...

永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器
一、原理介绍 传统滑模观测器采用如下结构: 传统SMO中LPF会带来相位延迟和幅值衰减,并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF),可以去除高次谐波,并且不用相位补偿就可以获得一个误差较小的转子位…...

聚六亚甲基单胍盐酸盐市场深度解析:现状、挑战与机遇
根据 QYResearch 发布的市场报告显示,全球市场规模预计在 2031 年达到 9848 万美元,2025 - 2031 年期间年复合增长率(CAGR)为 3.7%。在竞争格局上,市场集中度较高,2024 年全球前十强厂商占据约 74.0% 的市场…...

MySQL体系架构解析(三):MySQL目录与启动配置全解析
MySQL中的目录和文件 bin目录 在 MySQL 的安装目录下有一个特别重要的 bin 目录,这个目录下存放着许多可执行文件。与其他系统的可执行文件类似,这些可执行文件都是与服务器和客户端程序相关的。 启动MySQL服务器程序 在 UNIX 系统中,用…...