C++ 从无到有
文章平均质量分 92
BOSON_NEO
认识世界,认识自己
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
C++ 容器 迭代器和算法
容器我们发觉编写的每个程序都或多或少的要存储一些数据,此前C++在这方面只提供了几种最基本的方法:创建局部或全局变量来保存单个数据的值,以及使用数组来保存多个数据的值.此篇文章引出的概念:能容纳两个或更多值的数据结构,我们通常称之为容器(container)在C++标准库中有许多现成的容器,这个容器都经过不断的精心设计和测试封装,可以直接拿来使用,不过需要注意的是,找到最合适的容器只是编程工作的一部分,要实现程序的最优效率,还需一些适当的函数(算法)来处理这个容器内的数据.数组作为容器的弊端:原创 2020-12-05 18:08:33 · 950 阅读 · 0 评论 -
C++ 函数,类,内联模板
前言:此前我们已经了解了两种C++程序设计范型:1.面向过程式的范型(把程序划分成不同的函数).2.面向对象式的范型(把代码和数据组织成各种各样的类,并建立类之间的继承关系).C++程序设计范型除了上述两种,还有一种名为泛型编程的范型.泛型编程泛型编程技术支持程序员创建函数和类的蓝图(即模板template),而不是创建具体的函数和类.这些模板可以没有任何类型,所以它们可以处理任何类型的数据.当程序需要用到这些函数中的某一个时,编译器将根据模板即时生成一个能够对特定数据类型进行处理的代码版原创 2020-11-12 20:29:13 · 600 阅读 · 0 评论 -
C++ 链接和作用域
在上一个C++ 命名空间和模块化编程???? 项目中,我们已经开始创建由多个文件构成的项目,由于多文件导致程序命名空间和变量作用域的混乱,我们需要深入了解更复杂的变量作用域了 作用域的概念(scope)简单来说,变量作用域就是你可以在什么范围内访问这个变量,众所周知,一个在任何函数之前定义的变量可以在任何一个函数使用(即全局变量) .而在某个函数里定义的变量只能在那一个函数里使用(即局部变量).上述规则完全适用于单个源文件编译时的情况.那么,当一个项目由多个文件构成时,变量的作用域也会受到一定的影响原创 2020-11-07 15:50:42 · 498 阅读 · 0 评论 -
C++ 命名空间和模块化编程
头文件 什么是头文件,为什么需要头文件如果只用一个源文件来保存程序的全部代码,虽然这是可行的,但是这会给程序的编辑和修改工作带来诸多的不便(容易因为程序某处的小问题而牵一发动全身).为了规避这个问题,我们可以借助C++的预编译器和编译器的能力把一个复杂的应用程序划分成多个不同的文件,同时仍能保持它在内容和程序功能上的完整合理.C++预处理器的 #include指令,提供了一种能够让编译器在编译主程序的时候把其他文件的内容包括进来的机制.(例如用这个指令来包括 iostream这样的头文件)之所以要原创 2020-11-04 15:37:23 · 1463 阅读 · 1 评论 -
C++ 避免内存泄漏
内存泄漏前面我们讲过,分配了一个内存块但是忘记释放这个内存块会导致严重的问题,这样的内存块将等到程序执行结束时才会被释放如果这个程序运行很长时间(例如服务器,而且不是所有的操作系统都像windows一样每天都可以重启)且这个程序在运行过程中不断的申请新内存块(new),如果此时忘记释放那些已经不在使用的老内存块,老内存块将迟早将内存消耗殆尽,直接导致后边的new操作无法执行和程序崩溃!这样的编程漏洞称作内存泄漏(memory leak)作为 C++ 程序员,内存泄露始终是悬在头上的一颗炸弹。在过去几原创 2020-10-30 16:25:31 · 1894 阅读 · 0 评论 -
C++ 指针和引用
指针指针:对于一个类型T,[ T* ]就是指向T的指针类型,也即一个[ T* ]类型的指针变量能够保存一个T对象的地址,而这个类型T是可以加一些限定词的(const,volatile等…)通过指针,可以简化一些 C++ 编程任务的执行,还有一些任务,如 动态内存分配,没有指针是无法执行的,每一个变量都有一个内存位置,每一个内存位置都定义了可使用连字号(&)运算符访问的地址,它表示了在内存中的一个地址。请看下面的实例,它将输出定义的变量地址:const char c = 'A';const c原创 2020-10-29 21:32:06 · 526 阅读 · 1 评论 -
C++ 高级强制类型转换
传统的强制类型转换传统的强制类型转换:把所需要的指针类型放在一对圆括号之间,然后写出将被强制转换的地址值例如: Company *company = new TechCompany("APPLE","IOS"); TechCompany* techcompany = (TechCompany*)company;动态对象强制类型转换传统的强制类型转换仍有一个问题:那就是万一被强制转换的类型和目标类型结构完全不同时,程序却会继续进行强制转换,这样的程序相当危险,随时有可能崩溃或被崩溃!因为在类继原创 2020-10-25 17:07:30 · 867 阅读 · 1 评论 -
C++ 副本构造器
为什么需要副本构造器众所周知,我们可以把一个对象赋值给一个类型与之相同的变量,编译器将生成必要的代码把"源"对象各属性的值分别赋值给 "目标"对象的对应成员,这种赋值行为被称为逐位复制(bitwise copy)。这种行为在绝大多数场合都是没有问题的,但如果某些成员变量是指针的话,问题就来了:对象成员进行逐位复制的结果是你将拥有两个一模一样的实例,而这两个副本的同名指针会指向相同的地址…这样的话,当删除其中一个对象,它包含的指针也将被删除,但万一此时另一个副本(对象)还在引用这个指针,便会出现问题。那原创 2020-10-20 14:53:21 · 985 阅读 · 0 评论 -
C++ 从函数或方法返回动态内存(函数指针与指针函数)
动态内存的另一个常见用途是让函数申请并返回一个指向内存块的指针,也就是从函数返回内存(掌握这个机器是很重要的,尤其是当你打算使用由别人编写的库文件的时候)。如果不知道这个技巧,就只能让函数返回一个简单的标量值,如整型,浮点型或字符型。换句话说,它既不能返回一个以上的值,也不能返回数组值之类比较复杂的数据结构。...原创 2020-10-17 12:35:06 · 1454 阅读 · 0 评论 -
C++ 动态内存管理
到目前为止,我们实现的每一个程序在完成它的任务的时候使用的内存空间都是固定不变的,这个固定不变的内存空间在程序编写的时候就可以知道和确定(一般为变量的形式)。这些程序都不能在程序运行期间动态增加或减少内存空间,也就是说,只要程序里定义了变量,系统就会给这个变量分配固定的内存空间。但是C++必须支持动态的管理内存,比如说我们不可能要求用户输入的文本必须为固定字符。在很多时候,需要存储的数据量到底有多大在事先往往是一个未知的数,要想处理好这类的情况,我们就需要在C++程序中使用动态内存(程序能识别需要的内存大原创 2020-10-13 19:18:30 · 469 阅读 · 1 评论 -
C++ 内存分配
什么是内存 一个C/C++编译的程序占用内存分为以下几个部分: 栈区(stack):由 编译器自动分配和释放,存放的是 运行时函数分配的局部变量,函数参数,返回数据,返回地址等参数,其操作类似于数据结构中的栈。 堆区(heap):一般 由程序员手动分配,如果程序员没有释放,程序结束时可能由os回收,其分配类似于链表。 全局区(静态区static):存放全局变量,静态数据,常量。程序结束后由系统释放,全局区分为已初始化全局区(data)和未初始化全局区(bss)。 常量区(文字常量区):存放常量字符原创 2020-10-13 16:08:22 · 5294 阅读 · 1 评论 -
C++ assert函数与捕获异常
assert()函数C语言和C++都有一个专门为程序调试准备的工具函数,这就是assert()函数。这个函数在C语言的assert.h库文件里定义的,所以包含到C++的程序里我们用以下语句对此头文件进行包含:#include <cassert>assert()函数需要有一个输入参数,他将测试这个输入参数的真or假状态:如果这个输入参数的状态为真,程序什么都不做如果这个输入参数的状态为假,程序按照要求进行动作例如以下代码:int main(){ int i = 20; as原创 2020-10-09 16:42:48 · 4193 阅读 · 0 评论 -
C++ 错误处理和调试(编写代码前的准备工作)
错误处理程序出错的类型大概可以分为两类: 编译时错误(complie-time error) 和 运行时错误(run-time error)防止编译时错误的编程技巧:1:开始写代码之前先画出流程图。2:编译错误不要立刻修改源代码,应该先完整的审阅一遍源代码,再开始纠正错误。3:检查自己是否已经把所有必要的头文件全部include进源代码了。4:留意变量的作用域和命名空间。5:把调试好的代码另外保存起来并不再改动它,然后把这些代码划分成各个模块,需要的时候直接拉取代码即可。防止运行时错误原创 2020-10-06 20:51:09 · 824 阅读 · 0 评论 -
C++ 虚继承
虚继承首先,虚继承和虚函数是完全无相关的两个概念多继承(Multiple Inheritance)是指从多个直接基类中产生派生类的能力,多继承的派生类继承了所有父类的成员。尽管概念上非常简单,但是多个基类的相互交织可能会带来错综复杂的设计问题,命名冲突就是不可回避的一个。为什么要了解虚继承这一概念?因为上一节的多继承示例程序存在着一些隐患:多继承时很容易产生命名冲突,即使我们很小心地将所有类中的成员变量和成员函数都命名为不同的名字,命名冲突依然有可能发生,比如典型的是菱形继承,如下图所示:在多原创 2020-10-05 20:02:33 · 538 阅读 · 0 评论 -
C++ 多继承
要深入多继承的概念,首先要了解 继承的三种方式:公有继承(public),私有继承(private),保护继承(protected)三种继承方式的说明,如下表所示:原创 2020-10-05 15:48:12 · 1117 阅读 · 0 评论 -
C++ 操作符重载
输出操作符"<<" 和输入操作运算符">>"在C++中,左移运算符<<可以和cout一起输出,因此也常被称为"流插入运算符",或"输出运算符"。 但实际上!<<本来没有这样的功能,之所以能和cout一起使用来输出数据,是因为此<<操作符被重载了输出操作符"<<"cout是ostream类的对象,ostream类和cout都是在头文件 <iostream> 中声明的,ostream类将<<重载为其成员函数,原创 2020-10-03 17:44:30 · 1913 阅读 · 0 评论 -
C++ 运算符重载
为什么需要对运算符进行重载:C++预定义中的运算符(+ - * / …)的操作对象只局限于基本的内置数据类型(int float…),如果我们自定义了一个复数数据类型Complex comlex类有两个对象a和b,a为(3,4),b为(5,-10)。且需要求得a和b相加的值,此时c++中预定义的运算符无法对我们定义的复数类型数据ab进行运算,这个时候我们就需要对 “+” 号这个运算符进行重新定义,赋予其新的功能以满足自身需求,这个过程便称为运算符的重载。 建立一个复数类型Complexclass Co原创 2020-10-02 15:48:57 · 945 阅读 · 0 评论 -
C++ 抽象类
抽象类(接口)接口描述了类的行为和功能,而无需完成类的特定实现C++接口时通过抽象类实现的,设计抽象类的目的,是为了给其他类提供一个可以继承的适当的基类。抽象类本类不能被用于实例化对象,只能作为接口使用。如果试图实例化一个抽象类的对象,会导致编译错误。因此,如果一个抽象类的派生类需要被实例化(建立对象),则必须对每个继承来的纯虚函数进行函数体实现。如果没有在派生类中重写所有纯虚函数,就尝试实例化派生类的对象,也会导致编译错误这是因为 如果派生类没有实现父类的纯虚函数,则派生类变为抽象类抽象类与纯虚原创 2020-10-01 15:04:00 · 16839 阅读 · 2 评论 -
C++ 虚函数与多态性
多态性面向对象程序设计中的多态性是指向不同的对象发送同一个消息,不同对象对应同一消息产生不同行为。在程序中消息就是调用函数,不同的行为就是指不同的实现方法,即执行不同的函数体,也可以这样说就是实现了“一个接口,多种方法”...原创 2020-09-26 21:06:43 · 2458 阅读 · 0 评论 -
C++ 类对象与类指针(静态和动态多态)
代码:class Animal{public: virtual void eat() { cout << "我是动物 我在吃东西" << endl; }};void main(){ //建立类对象 animalAnimal animal;animal.eat(); //建立类指针 animalAnimal* animal = new Animal;//建立类型为Animal的类对象(new Animal) animal, 指向Animal类的指针(原创 2020-09-22 21:30:23 · 2744 阅读 · 0 评论 -
C++ new和delete动态分配和释放内存
关于C++的关键字兼运算符: new和deletenewnew其实就是告诉计算机开辟一段新的空间,但是和一般的声明不同的是, new开辟的空间在堆上,而一般声明的变量存放在栈上 。通常来说,当在局部函数中new出一段新的空间,该段空间在局部函数调用结束后仍然能够使用,可以用来向主函数传递参数。另外需要注意的是, new的使用格式,new出来的是一段空间的首地址 。所以一般需要用指针来存放这段地址 为什么需要new来开辟内存空间:比如说 数组的长度是预先定义好的,在整个程序中固定不变。C++ 不允原创 2020-09-22 21:29:50 · 4014 阅读 · 0 评论 -
C++ this指针与静态属性的关系
关于静态的说明:1.静态成员是所有对象共享的,所以 不能在静态方法里面访问非静态元素2.非静态成员,可以访问类的静态成员和类的非静态成员C++内存的分配方式要想理解this指针和静态属性的关系,需要先了解C++内存的分配方式一个由C/C++编译程序占用内存分为以下几个部分:栈区(stack) -由 编译器自动分配和释放,存放函数参数值,局部变量值,返回地址等。操作方式类似于数据结构中的 栈 。栈内存分配时的运算 内置于处理器指令集中, 效率很高但分配内存的容量有限(VC6下,默认的栈空间大小为原创 2020-09-18 19:49:26 · 450 阅读 · 0 评论 -
C++ 静态属性和静态方法
静态静态成员是所有对象共享的,所以不能在静态方法里面访问非静态元素但非静态方法可以访问类的静态成员及非静态成员静态数据成员 1.静态数据成员的声明静态数据成员实际上是类域中的全局变量(类中的静态成员数据和函数都只是相当于声明的作用,而不是定义 声明不分配空间 在类里面只有const static才可以进行数据定义(初始化),作为常量使用,const或者static都不可以)2.静态数据的定义必须在.cpp文件中定义 否则就会出现无法识别外部符号的错误3.静态数据成员的作用域静态数据成员被类的原创 2020-09-16 16:45:59 · 12551 阅读 · 2 评论 -
C++ 覆盖方法与重载方法
覆盖方法(overriding)什么是函数的覆盖方法覆盖方法用于同一函数的重写 —— 派生类函数覆盖基类同名函数覆盖方法重写(覆盖)了一个方法,以实现不同的功能。一般是用于子类在继承父类时,重写(重新实现)父类中的方法覆盖方法的特征:范围不同(分别位于 基类 和 派生类中)函数名字相同函数参数相同基类函数必须有virtual(虚函数)关键字为什么需要覆盖方法:在 C++ 里,当我们需要在 基类里提供一个通用的函数,但是在它的某个子类里,需要修改这个方法(通用函数)的实现,就要用到覆盖方原创 2020-09-15 20:40:07 · 2102 阅读 · 0 评论 -
C++ 访问控制
什么是访问控制C++标准中定义了三种类成员访问控制符 public, protected和private,分别译为公有的、保护的、私有的 这是在类的内部声明这三种控制符的意思为什么需要访问控制访问控制就是C++提供的一种用来保护类里的方法和属性的手端保护-对谁可以调用某个方法和访问某个属性加上一个限制 如果某个对象试图调用一个它无权进行访问的函数 编译器将报错控制符访问特点(1)public成员:能被 本类的成员函数 (此类中任何类型的控制符声明的成员函数都可以访问)、友元函数、本类的对象、原创 2020-08-25 15:52:55 · 1188 阅读 · 1 评论 -
C++ 继承机制中的构造器与析构器
继承机制中构造器和析构器的特性在构造器与析构器项目中 我们知道C++支持程序员自定义 建立或销毁一个对象时自动调用的方法(构造器和析构器)在没有类继承的情况下构造器与析构器的运行规则系统在创建某个类的实例时会第一时间自动调用这个类的 构造器对象消亡时,析构器自动被调用,用来释放对象占用的空间在类继承的情况下构造器与析构器的运行规则 基类的构造器将在子类的构造器调用之前被调用这是由于基类必须在子类之前被初始化的原则所导致的 与构造器的情况相反 基类的析构器将在子类的最后一条语句执行完毕后才被原创 2020-08-24 14:10:24 · 560 阅读 · 0 评论 -
C++ this指针 与 类的继承
一 . this指针不进行详细解释 一般情况下用不着#include <iostream>using namespace std;class Human { char james; Human(char james);//构造函数 传入参数};Human::Human(char james)//对构造函数进行初始化{ james = james; //在fishc=fishc之前 所有的语法没有任何问题 虽然Human构造器中有一个名为james的参数 //虽然他原创 2020-08-22 21:32:10 · 919 阅读 · 0 评论 -
C++ 构造函数与析构函数
构造器和析构器的作用1.C++构造函数和析构函数主要负责构建对象和销毁对象,在构建对象的时候系统自己调用类中的构造函数, 在对象作用域结束后,调用析构函数销毁对象2.构造函数用来完成事先的初始化和准备工作**(申请分配内存),析构函数用来完成事后所必须的清理工作(清理内存)**构造器(constructed)定义构造器的前提(面对对象编程技术开发程序的基本步骤)定义一个有属性和方法的类(模板)为该类创建一个变量(实现)构造器是类中一种特殊的方法(成员函数) 构造器和通常方法的主要区别原创 2020-08-22 14:50:15 · 385 阅读 · 0 评论 -
C++ 类与对象
一.类的构成1.1 类与结构类由结构体演变而来 两者之间虽然相似 但是也有很大的差异结构是C的一种自定义的数据类型,它把相关联的数据元素组成一个单独的统一体#include <iostream.h>struct Date { int year; int month; int day;};int main(){ Date date1; date1.year=2003; date1.month=8; date1.day=25;原创 2020-08-20 18:45:36 · 719 阅读 · 0 评论 -
C++联合枚举和类型别名
联合 union联合是一种特殊的类 一个union联合可有多个数据成员 这些数据成员共同使用同一片存储空间 (可以节省内存)1.分配给一个union对象的存储空间至少要能容纳它的最大数据成员2.union 不能含有引用类型的成员,默认情况下,union的成员都是公有的,这一点和struct相同3.union既不能继承自其他类,也不能作为基类使用,所以在union中不能含有虚函数4.为union的一个数据成员赋值时会令其它数据成员变成未定义的状态 联合//可以像创建结构一样创建联合unio原创 2020-08-19 12:23:14 · 517 阅读 · 0 评论 -
C++ 对象的基础(结构及结构指针)
结构:结构(Structure)是一种由程序员定义的,由其他变量类型组合而成的数据类型定义一个结构的基本语法是:struct name{ type varName1; type varName2;};注意后面还有一个分号当需要处理一些具有多种属性的数据时,结构往往是很好的选择例如编写一个个人信息管理程序时,涉及到的基本特征有:名称、账号、性别等struct IDmation{ //声明三个成员变量 string name; string ID; char s原创 2020-08-18 16:14:33 · 826 阅读 · 0 评论 -
C++ 结构体
什么是结构体结构体是一个由程序员定义的数据类型,可以容纳许多不同的数据值。在过去,面向对象编程的应用尚未普及之前,程序员通常使用这些从逻辑上连接在一起的数据组合到一个单元中。一旦结构体类型被声明并且其数据成员被标识,即可创建该类型的多个变量,就像可以为同一个类创建多个对象一样结构体声明声明结构体的方式和声明类的方式大致相同,其区别如下使用关键字 struct 而不是关键字 class尽管结构体可以包含成员函数,但它们很少这样做。所以,通常情况下结构体声明只会声明成员变量。结构体声明通常不包括原创 2020-08-18 12:57:06 · 424 阅读 · 0 评论 -
C++ 复杂的数据类型(指针)
计算机的内存地址和指针的关系指针,就是一个存储计算机内存地址的一个变量,通过这个变量,可以很方便的操作内存中的值创建变量时 系统将分配一些内存块用保存他们的值 每个内存块拥有一个独一无二的地址 变量的地址可以用 & 取地址符取得 这便是指针C++中指针的特性C++中允许多个指针指向同一个值C++支持无类型指针 就是没有被声明为某种特定类型的指针 例如 void*pointer 对于一个无类型指针进行解引用前 必须先把他转换为适当的数据类型案例一使用reinterpret原创 2020-08-16 14:02:49 · 659 阅读 · 0 评论 -
复杂的数据类型(string数据类型)
#include <iostream>#include <string>//为了使用getline函数和在我们的程序中使用string类型 包含string字符头文件using namespace std;//#define ITEM 10//使用宏定义变量void CalcSum();void String();int main(){// CalcSum(); String();}案例一 输入10个整型变量并计算其总数和平均数及输入数据的原创 2020-08-15 16:53:06 · 449 阅读 · 0 评论 -
C++ 函数的重载
一 . c++函数重载的定义:一个作用域 三个不同同一作用域内,一组函数的函数名相同,参数列表不同(参数个数不同/参数类型不同),返回值可同可不同二 . 函数重载的作用重载函数通常用来在同一个作用域内 用同一个函数名 命名一组功能相似的函数,这样做减少了函数名的数量,避免了名字空间的污染,对于程序的可读性有很大的好处三. 函数重载是一种静态多态(1)多态:用同一个东西表示不同的形态(2)多态分为: 静态多态(编译时的多态)动态多态(运行时的多态)(3)函数重载是一种静态多态四.c++原创 2020-08-14 17:12:06 · 451 阅读 · 0 评论 -
C++ 输入输出例程
#include <iostream>using namespace std;void YorN();void CorF();int main(){ //YorN();//todo用户输入字符进行条件判断程序 //CorF();//todo用户输入字符信息和整型变量信息进行温度类型转换 return 0;}void YorN(){ //todo程序向用户提出一个Y/N问题 把用户输入的值赋值给answer变量 //todo要求 针对用户输入的Y或y N或n原创 2020-08-13 20:19:00 · 317 阅读 · 0 评论 -
C++ 文件IO流
什么是文件IO流首先需要包含文件IO操作流头文件fstream#include <fstream> //文件IO操作流头文件 fstream文件的读取类ifstream声明读取文件所需要的输入流类变量 并 建立流对象使用ifstream类中的open成员函数 连接指定文件关于open打开文件函数中的第二个参数 – 使用方式ios::in -- 打开一个可读取文件 (以输入的方式打开文件)ios::out -- 打开一个可写入文件 (以输出的方式打开文件,如果已有此名字的原创 2020-08-12 21:15:22 · 678 阅读 · 0 评论 -
C++ 输入与输出流(cin与cout)
认识C++ 一个完整C++程序应包含哪些要素IDE – Integrated Developed Environment 集成开发环境一个函数定义 包括四部分返回类型(return type)函数名( function name)一个括号包围的形参列表(parameter list,允许为空)以及函数体(function body)初识输入输出C++并未定义任何输入输出(io)语句C++以包含全面的标准库来提供IO机制关于iosteam库 包含两个基础类型 istream和os原创 2020-08-11 19:53:04 · 2142 阅读 · 0 评论
分享