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,也…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...

Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...

听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...

深度学习水论文:mamba+图像增强
🧀当前视觉领域对高效长序列建模需求激增,对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模,以及动态计算优势,在图像质量提升和细节恢复方面有难以替代的作用。 🧀因此短时间内,就有不…...

mac 安装homebrew (nvm 及git)
mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用: 方法一:使用 Homebrew 安装 Git(推荐) 步骤如下:打开终端(Terminal.app) 1.安装 Homebrew…...

破解路内监管盲区:免布线低位视频桩重塑停车管理新标准
城市路内停车管理常因行道树遮挡、高位设备盲区等问题,导致车牌识别率低、逃费率高,传统模式在复杂路段束手无策。免布线低位视频桩凭借超低视角部署与智能算法,正成为破局关键。该设备安装于车位侧方0.5-0.7米高度,直接规避树枝遮…...

DBLP数据库是什么?
DBLP(Digital Bibliography & Library Project)Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高,数据库文献更新速度很快,很好地反映了国际计算机科学学术研…...