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,也…...
Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
nnUNet V2修改网络——暴力替换网络为UNet++
更换前,要用nnUNet V2跑通所用数据集,证明nnUNet V2、数据集、运行环境等没有问题 阅读nnU-Net V2 的 U-Net结构,初步了解要修改的网络,知己知彼,修改起来才能游刃有余。 U-Net存在两个局限,一是网络的最佳深度因应用场景而异,这取决于任务的难度和可用于训练的标注数…...
c# 局部函数 定义、功能与示例
C# 局部函数:定义、功能与示例 1. 定义与功能 局部函数(Local Function)是嵌套在另一个方法内部的私有方法,仅在包含它的方法内可见。 • 作用:封装仅用于当前方法的逻辑,避免污染类作用域,提升…...
JDK 17 序列化是怎么回事
如何序列化?其实很简单,就是根据每个类型,用工厂类调用。逐个完成。 没什么漂亮的代码,只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…...
Python常用模块:time、os、shutil与flask初探
一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...
基于开源AI智能名片链动2 + 1模式S2B2C商城小程序的沉浸式体验营销研究
摘要:在消费市场竞争日益激烈的当下,传统体验营销方式存在诸多局限。本文聚焦开源AI智能名片链动2 1模式S2B2C商城小程序,探讨其在沉浸式体验营销中的应用。通过对比传统品鉴、工厂参观等初级体验方式,分析沉浸式体验的优势与价值…...
