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,也…...
分布式机器学习中的精度与效率权衡:从近似计算到自动驾驶实践
1. 项目概述:当“算得准”遇上“算得快”在分布式机器学习的世界里,我们每天都在面对一个看似简单、实则深刻的抉择:是要一个“算得准”但慢吞吞的模型,还是要一个“算得快”但偶尔会出点小错的系统?这个抉择ÿ…...
AI系统误差传播建模:从仿真数据生成到高效参数估计的完整方案
1. 项目概述:当AI系统出错时,误差是如何“传染”的?在自动驾驶汽车、工业机器人或者医疗影像诊断这类复杂的人工智能系统里,一个常见的架构是“流水线”式的多阶段处理。比如,一辆自动驾驶汽车先通过摄像头和激光雷达“…...
开源AI编辑器的未来发展趋势
基于当前发展状况来分析,开源AI编辑器的未来发展趋势主要体现在以下几个核心方向:一、技术能力:从“辅助补全”迈向“智能体化”全流程自主化:AI编辑器正从基础的代码补全、语法检查,向具备自主决策能力的智能体&#…...
储能 PACK 与 BMS:怎么识别有真实出货的系统集成厂,避开组装贴牌
储能赛道的门槛看起来不高:买一批电芯,叫几家代工厂组装成 PACK,挂上自己的品牌,就能对外声称是"储能系统集成商"。这条路在 2021 年到 2024 年的行业高速期被走通过无数次。于是,有真实产线、真实并网项目、…...
Python数据库设计模式:从ORM到数据层架构
Python数据库设计模式:从ORM到数据层架构 引言 数据库设计是后端开发的核心环节。作为从Python转向Rust的后端开发者,我发现Python的数据库生态非常成熟,尤其是SQLAlchemy提供了强大的ORM能力。本文将深入探讨Python数据库设计模式࿰…...
Oracle EBS关联公司段的设计逻辑和设计哲学
从设计逻辑 → 核心原理 → 完整配置事例 → 业务分录实例 → 常见坑的完整说明,全部围绕 “关联公司段(Intercompany Company Segment)” 在 EBS R12 里的设计与实现,不绕弯一、关联公司段的 “设计核心逻辑”1. 本质定义关联公司…...
关于fiddler报错“The system proxy was changed. click to reenable capturing”的解决办法
背景:第一次下载安装fiddler,安装过程没有任何问题,但启动即报错 参考了很多帖子,一个一个排查后,发现是sslvpn的问题(因为访问校园网需要安装了 EasyConnect 深信服SSLVPN客户端),把…...
全球AI范式变革与中国产业的破局路径
全球AI范式变革与中国产业的破局路径摘要当前全球人工智能产业正处于范式切换的关键节点,底层技术路线的竞争已经从参数规模竞赛转向认知框架的本质性革新。本文基于2026年行业最新发展动态,系统分析当前主流AI范式的内生性缺陷,梳理中美AI产…...
企业AI编程效率提升:2026最新权威AI编程工具必看
企业AI编程效率提升:2026最新权威AI编程工具必看开篇“企业研发团队效率低下,核心项目交付周期长,如何通过AI编程工具缩短开发周期、提升ROI?”“企业部署AI编程工具,如何兼顾安全合规、代码质量与开发效率,…...
岩土工程渗流问题之有限单元法--坝基渗流、围堰、土石坝自由面、黏土垫层防渗、污染土固化后渗控
第一天 有限元编程基础知识1.有限单元法基础简介(离散化、存储策略及方程解法、边界条件的处理)2.编程语言Fortran及编译工具Intel Visual Fortran(IVF)简介3.Fortran/Matlab/Julia等开源代码及程序库(geomlib/femlib)简介4.水工…...
