C++
文章平均质量分 82
夏日岛歌
这个作者很懒,什么都没留下…
展开
-
命名空间和模块化编程1
模块化- 把程序划分为多个组成部分(即所谓的“模块”)- 这是通过把程序代码分散到多个文件里,等变异程序时再把那些文件重新组合在一起实现的。命名空间(namespace)- 这个概念相比起C语言是C++里新增加的东西,编写的程序越多、编写的程序越复杂,就越需要使用命名空间。头文件只有一个源代码文件来保存程序的全部代码是可行的,但那会给编辑修改工作带来诸多不便。我们可以借...原创 2019-04-15 12:10:23 · 171 阅读 · 1 评论 -
副本构造器
我们都知道,可以把一个对象赋值给一个类型与之相同的变量。编译器将生成必要的代码把“源”对象各属性的值分别赋值给“目标”对象的对应成员。这种赋值行为称之为逐位赋值(bitwise copy)这种行为在绝大多数场合都没有问题,但如果某些成员变量是指针的话,问题就来了:对象成员进行逐位复制的结果是你将拥有两个一模一样的实例,而这两个副本里的同名指针会指向相同的地址。于是乎,当删除其中一个对象...原创 2019-04-11 22:40:55 · 538 阅读 · 3 评论 -
静态属性和静态方法和static的用法
面对对象编程技术的一个重要特征是用一个对象把数据和对数据处理的方法封装在一起。大家还记得,在前面的例子里我们一直是在使用对象(也可以说是某个类的实例)来调用方法,每个方法只处理调用它的那个对象所包含的数据,所有的数据都属于同一个对象。这就引发了一个问题:如果我们所需要的功能或者数据不属于某个特定的对象,而是属于整个类的,该怎么办?我们不妨假设现在需要统计一下有多少只活的动物,那么我们需...原创 2019-03-29 11:26:24 · 936 阅读 · 0 评论 -
运算符重载
所谓重载,就是重新赋予新的含义。函数重载是对一个已有的函数赋予新的含义,使之实现新功能。其实运算符也可以重载,实际上,我们常常在不知不觉之中使用了运算符重载。运算符重载的方法是定义一个重载运算符的函数,在需要执行被重载的运算符时,系统就自动调用该函数,以实现相应的运算。也就是说,运算符重载是通过定义函数实现的。运算符重载实质上是函数的重载。重载运算符的函数一般格式如下:函...原创 2019-04-02 18:14:15 · 1913 阅读 · 0 评论 -
从函数或方法返回内存还有函数指针和指针函数
动态内存的另一个常见用途是让函数申请并返回一个指向内存块的指针。掌握这个技巧很重要,尤其是在你打算使用由别人编写的库文件时。如果不知道这个技巧,就只能让函数返回一个简单的标量值,如整型、浮点型或字符型。换句话说,它既不能返回一个以上的值,也不能返回数组之类比较复杂的数据结构。可以这样说,只要你想让函数返回的东西不是一个简单的值,就需要学习本讲内容。这个技巧的基本思路并不复杂:在函数...原创 2019-04-10 23:58:52 · 201 阅读 · 0 评论 -
动态数组
虽然,前面我们讲过的用new给基本类型和对象在运行时分配内存,但它们的尺寸在编译时就已经确定下来--因为我们为之申请内存的数据类型在程序里有明确的定义,有明确的单位长度!可是,总有些时候,必须要等到程序运行时才能确定需要申请多少内存,甚至还需要根据程序的运行情况追加申请更多的内存。从某种意义上讲,这样的内存管理才是真正的动态!这一讲中,我们将带大家编写一个程序为一个整数型数组分配内存,实...原创 2019-04-10 17:46:52 · 494 阅读 · 0 评论 -
友元关系
在编程中我们通过public,protected和private这些访问级别可以让程序员控制谁有权使用某个类里的某个方法和属性。这个强大的方案可以把代码的实现细节隐藏起来,不让没有相应权限的其他代码访问到。可是在某些场合,一个完全无关的类由于某些特殊原因需要访问到某个protected成员,甚至某个private成员,那该怎么办呢?有些朋友可能会说,那就把所有的东西都声明为public吧。...原创 2019-03-28 00:55:36 · 1759 阅读 · 1 评论 -
覆盖方法和重载方法
通过之前的学习,我们已经知道了如果通过创建新的子类来重用现有的代码(继承)。虽然这个方案可以让我们轻松解决许多现实世界里的问题,但在某些场合,却又显得不够用。例如当我们需要在基类里提供一个通用的函数,但在它的某个子类需要修改这个方法的实现,在C++,覆盖(overriding)就可以做到。回到之前的例子,我们都知道,但凡是个动物都知道吃,那么吃就可以说是动物的一个共同特征,但是我们知道...原创 2019-03-27 22:26:59 · 234 阅读 · 0 评论 -
动态内存管理
到目前为止,演示过的所有的程序在完成它的任务时所使用的内存空间都是固定不变的。这个固定不变的内存空间其实是在编写程序时就可以知道和确定(一般以变量的形式)。这些程序都是不能在程序运行期间动态增加或减少内存空间。你见过要求用户输入的文本必须不多不少包含多少个字符的程序吗?这是不现实的。在很多时候,需要存储的数据量到底有多大在事先往往是一个未知数,要想处理好这类情况,就需要在C++程序里使...原创 2019-04-10 16:31:13 · 95 阅读 · 0 评论 -
抽象方法和多态性
抽象方法(abstract method),也可以称为纯虚函数,是面向对象编程技术的另一个核心概念,在设计一个多层次的类继承关系时市场会用到。把某个方法声明为一个抽象方法等于告诉编译器这个方法必不可少,但我现在(在这个基类里)还不能为它提供一个实现!上一个例子里有一个Pet::play(),在当时把每一个都输,但是在现实中不存在什么都玩的宠物,每种宠物都有自己的玩法,而我们的应对措施是输出...原创 2019-03-31 23:05:51 · 246 阅读 · 0 评论 -
assert函数和捕获异常
C语言和C++都有一个专为调试而准备的工具函数,就是assert()函数。这个函数实在C语言的assert.h库文件里定义的,所以包含到C++程序里我们用一下语句:#include <cassert>assert()函数需要有一个参数,它将测试这个输入参数的真or假状态。如果为真,Do nothing!如果为假,Do something!例子:#incl...原创 2019-04-10 12:21:47 · 797 阅读 · 0 评论 -
虚方法以及new和delete讲解
先通过一个简单的例子引发的问题来探究虚方法的作用以及完整的解决方案。下面先讲解一下new和delete的作用。new和delete以前我们的做法是:创建一个变量,再把这个变量的地址赋值给一个指针。然后我们就可以利用指针来访问这个变量的值了。事实上,在C和C++中我们完全可以在没有创建变量的情况下为有关数据分配内存,也就是直接创建一个指针并让它指向新分配的内存块,用法如下:#i...原创 2019-03-31 20:52:58 · 227 阅读 · 0 评论 -
错误处理和调试:让函数返回错误代码
程序出错可以分为两大类:编译时出错(complie-time error)运行时出错(run - time error)让程序能够自行处理潜在错误的办法之一是创建一些测试函数:专门测试某种条件并根据测试结果返回一个代码来表示当前函数的执行状态。int myFunction(){ if (condition) { return 0; } else { retur...原创 2019-04-10 10:45:36 · 312 阅读 · 0 评论 -
运算符重载课后练习
重载运算符“+”,“-”,“*”,“/”实现有理数的加减乘除运算,如1/8 + 7/8 = 1,1/8 - 7/8 = -6/8,1/8 * 7/8 = 7/64,1/8 / 7/8 = 1/7,首先是自己写的,也实现了这个功能,但是限制很多,不好。#include <iostream>class Rational{public: Rational(); Ration...原创 2019-04-08 20:04:21 · 377 阅读 · 0 评论 -
重载左移操作符,也就是插入器
因为上节那个重载操作符课后练习的代码里面要多次调用print方法才能实现分数打印,所以改进一下这里通过重载<<操作符来实现print打印分数的功能(<<官方叫插入器)下面是一个operator<<()函数的原型:- std::ostream& operator<<(std::ostream& os, Rational...原创 2019-04-08 20:48:59 · 136 阅读 · 0 评论 -
避免内存泄漏
前面我们讲过,分配了一个内存块但忘记了释放它这是一个严重的错误,这样的内存块要等到程序执行结束时才会被释放掉(不懂的话就看栈的相关介绍)。如果程序运行很长时间(例如在服务器上,注意不是所有的操作系统都像windows一样每天都要重启)并且在不停地申请新内存块,忘记释放那些已经不再有用的老内存块将迟早会把内存消耗殆尽,直接导致后面的new操作无法执行甚至是崩溃。这样的编程漏洞我们称之为内存泄...原创 2019-04-14 16:04:53 · 176 阅读 · 0 评论 -
容器和算法
渐渐地我们发觉编写的每一个程序都或多或少地需要存储一些数据,而C++这方面只提供了集中最基本的方法。你可以创建局部或全局变量来保存单个值,可以使用数组来保存多个值。今天的概念:能容纳两个或更多个值的数据结构通常我们称为容器(container)。这么说来,数组是C++唯一直接支持的容器,但数组并不适合用来解决所有的问题。如果打算编写一个简单的拼写检查程序,应该怎么做?首先想到的...原创 2019-04-17 01:28:45 · 203 阅读 · 0 评论 -
高级对象强制类型转换
静态对象强制类型转换还是那个例子#include <iostream>#include <string>class Company{public: Company(std::string theName, std::string product); virtual void printInfo();protected: std::string ...原创 2019-04-14 14:26:26 · 181 阅读 · 0 评论 -
内联模板
内联函数内联即inline,首先想到的是内联函数,引入内联函数的目的是为了解决程序中函数调用的效率问题。内联函数从源代码层看,有函数的结构,而在编译后,却不具备函数的性质。编译时,类似宏替换,使用函数体替换调用处的函数名。一般在代码中用inline修饰,但能否形成内联函数,需要看编译器对该函数定义的具体处理。举个例子:inline int add(int x, int y, ...原创 2019-04-16 23:01:30 · 640 阅读 · 0 评论 -
类模板
类模板和函数模板非常相似:同样是先由你编写一个类的模板,再由编译器在你第一次使用这个模板时生成实际代码。template <class T>class MyClass{ MyClass(); void swap(T &a, T &b);}构造器的实现将是下面这样:MyClass<T>::MyClass(){ /...原创 2019-04-16 17:33:22 · 102 阅读 · 0 评论 -
基本的模板语法,泛型编程
到目前为止,我们已经介绍了两种C++程序设计范型,即:- 按照面向过程式范型把程序划分成不同的函数- 按照面向对象式范型把代码和数据组织成各种各样的类并建立类之间的继承关系。泛型编程泛型编程技术支持程序员创建函数和类的蓝图(即模板,template),而不是具体的函数和类。这些模板可以没有任何类型:它们可是处理的数据并不限于某种特定的数据类型。当程序需要用到这些函数中的某一...原创 2019-04-16 16:53:59 · 195 阅读 · 0 评论 -
链接和作用域2
header.h#pragma once#ifndef HEADER_H#define HEADER_Hunsigned long returnFactorial(unsigned short num);unsigned short headerNum = 5;#endifthat.cpp#include "header.h"unsigned short tha...原创 2019-04-16 11:49:38 · 119 阅读 · 0 评论 -
链接和作用域
作用域前面已经创建了由多个文件构成的项目,是时候再来讨论更复杂的变量作用域了。简单的理解,变量的作用域就是你可以再什么范围内访问这个变量。我们都知道,一个在任何函数之前定义的变量可以在任何一个函数里使用(这是一个全局变量),而在某个函数里定义的变量只能在那一个函数里使用(这是一个局部变量)。那么,当一个项目由多个文件构成时,变量的作用域也会受到一定的影响!链接与作用域有关的...原创 2019-04-15 20:21:35 · 231 阅读 · 0 评论 -
命名空间和模块化编程3,命名空间
我们都知道,创建的每一个类、函数和变量都只能在一定的区域内使用。而我们所知道最大的区域是全局作用域,最小的区域是一个代码块,例如:{ int a = 20;}//a在此处已经不存在随着程序变得越来越复杂,全局作用域里的东西越来越多,尤其是在使用外部函数库时。这可就会导致必须把名字取得很长才会让它们不重名。这正是“命名空间”(namespace)的作用。命名空间其实...原创 2019-04-15 17:29:13 · 163 阅读 · 0 评论 -
命名空间和模块化编程2,重点有实例和C++预处理器
创建实现文件回到Rational这个例子,来进一步实现模块化编程。- rational.h头文件包含Rational类的声明,但不包含这个类的实现代码。- 这种分割可能刚开始接触的朋友觉得有点奇怪,但在视线中非常普遍。- 因为把接口(函数的原型)和实现(函数体的定义)分开是对代码进行模块化的基本原则之一。头文件的重要性不仅体现在可以告诉编译器某个类、结构或函数竟有着怎样的行为,...原创 2019-04-15 16:20:10 · 155 阅读 · 0 评论 -
虚继承
前一节的student示例程序看起来似乎已经解决了问题,但它存在着一些隐患。首先,在TeachingStudent类的introduce()方法里,我们不得不明确的告诉编译器应该使用哪一个属性这对于classes属性来说是应该的,因为教一门课和上一门课有着本质的区别,而作为常识,助教教的课和他学的课不可能一样!但是我们再深入考虑下,既然在TeachingStudent对象里可以继承两个...原创 2019-04-09 07:57:32 · 105 阅读 · 0 评论 -
多继承
多继承(multiple inheritance)可是是面向对象编程技术中心最惹人争议的功能了。这个概念乍看起来很简单,但它可能引起一些难以预料的后果。因此,java和c#等面向对象编程语言大都只支持多继承的最简单的版本。什么时候需要用到多继承?- 只要你遇到的问题无法只用一个“是一个”关系来描述的时候,就是多继承出场的时候- 举个例子:在学校里有老师和学生,他们都是人(...原创 2019-04-08 22:39:10 · 1499 阅读 · 0 评论 -
静态属性和静态方法2以及this指针的又一些说明
关于静态的一些说明:- 静态成员是所有对象共享的,所以不能在静态方法里面访问非静态元素- 非静态方法可以访问类的静态成员,也可以访问类的非静态成员。C++内存分配方式详解——堆、栈、自由存储区、全局/静态存储区和常量存储区回顾下:this指针是类的一个自动生成、自动隐藏的私有成员,它存在于类的非静态成员函数中,指向被调用函数所在的对象的地址。- 当一个对象被创建时,该对象的th...原创 2019-03-31 17:38:47 · 213 阅读 · 0 评论 -
访问控制
在此前的例子里,我们无论是Animal,Pig和Turtle类里的所有成员都是用public:语句声明。所谓访问控制,就是C++提供了一种用来保护类里的方法和属性的手段这里所说的保护的意思是对谁可以调用某个方法和访问某个属性加上一个限制。如果某个对象试图调用一个它无权访问的函数,编译器将报错。我们看下C++的访问级别: 级别 ...原创 2019-03-26 16:03:17 · 229 阅读 · 0 评论 -
cout、ceer、clog三者区别
之前一直在用,但就是没在意两者到底有啥却别,今天又想到这个问题,总结下吧(以下的内容均是本人从网上查阅资料看来整理的,暂时还没有查阅官方资料,不保证准确,欢迎讨论)其实大家平常常会用的主要有三个:cout、cerr、clog,首先简单介绍下三者。这三者在C++中都是标准IO库中提供的输出工具(至于有关的重载问题在此不讨论):cout:写到标准输出的ostream对象;cerr:输出...转载 2019-03-08 10:38:36 · 2007 阅读 · 0 评论 -
C++中重定向的意思。
重定向,就是:把 原来的 cin 从键盘输入 改为从文件输入。把 原来的 cout 向屏幕输出 改为输出到文件。例如: cin>>line; 原来要从键盘拍入。现在自动到某文件读取,语句还是 cin>>line; 不变。cout << line << endl; 原来向屏幕输出,现在自动写到某文件里,语句还是cout << lin...转载 2019-03-08 10:28:56 · 771 阅读 · 0 评论 -
理解变量、指针、地址
https://fishc.com.cn/thread-35164-1-1.html,从这里转载转载 2019-03-12 10:53:53 · 172 阅读 · 0 评论 -
利用重载函数的方法设计一个程序,该程序通过函数“calc()”进行计算并返回显示结果。
要求:1. 当传入一个参数时,计算该参数的平方值;2. 当传入两个参数时,计算两个参数的乘积;3. 当传入三个参数时,计算三个参数的和。#include <iostream>using namespace std;int calc(int num);int calc(int num, int num1);int calc(int num, int num1,...原创 2019-03-12 10:52:06 · 1653 阅读 · 0 评论 -
对象的基础--结构,还有结构与指针
结构:结构(Structure)是一种由程序员定义的,由其他变量类型组合而成的数据类型定义一个结构的基本语法是:struct name{ type varName1; type varName2;};注意后面会有一个分号。当需要处理一些具有多种属性的数据时,结构往往是很好的选择例如编写一个鱼油管理程序时,涉及到的基本特征有:姓名、身份证、性别等s...原创 2019-03-20 10:38:11 · 205 阅读 · 0 评论 -
函数的重载实例
#include <iostream>void convertTemperature(double tempIn, char typeIn);void convertTemperature(int tempInInt, char typeIn);int main(){ double tempIn; int tempInInt; char typeI...原创 2019-03-11 16:20:16 · 1867 阅读 · 0 评论 -
接复杂数据类型4,指针与数组的应用举例,重载和泛型程序设计
1. 重载#include <iostream>using namespace std;void print (int *pBegin, int *pEnd);void print (char *pBegin, char *pEnd);int main(){ int num[5] = { 0,1,2,3,4, }; char name[5] = { 'F', '...原创 2019-03-19 22:04:47 · 137 阅读 · 0 评论 -
复杂数据类型4:指针与数组,其中讲了reinterpret_cast
#include <iostream>using namespace std;int main(){ const unsigned short ITEMS = 5; int intArray[ITEMS] = { 1, 2, 3, 4, 5 }; char charArray[ITEMS] = { 'F', 'i', 's', 'h', 'C' }; int *i...原创 2019-03-19 17:30:31 · 446 阅读 · 0 评论 -
cin对象用来报告其工作情况的成员函数
-eof():如果到达文件(或输入)末尾,返回true;-fail():如果cin无法工作,返回true;-bad():如果cin因为比较严重的原因(例如内存不足)而无法工作,返回true;-good():如果情况都没有发生,返回true。...原创 2019-03-10 16:42:57 · 303 阅读 · 0 评论 -
摄氏度和华氏度转换?自己写的几种垃圾程序,里面有swithc和case
先是第一种,需要用户自己先选择时摄氏度还是华氏度,不好用#include <iostream>using namespace std;int main(){ char FC; cout << "请选择输入的是摄氏度C还是华氏度F?" << "\n"; cin >> FC; float temp; float tempC; ...原创 2019-03-09 20:36:19 · 5674 阅读 · 0 评论 -
C++中"\n"与endl的区别是什么?以及std::cout 小于号小于号endl;不能用的原因
"\n"表示内容为一个回车符的字符串。std::endl是流操作,输出的作用和输出"\n"类似,但可能略有区别。std::endl输出一个换行符,并立即刷新缓冲区。例如,std::cout << std::endl;相当于std::cout << '\n' << std::flush;,或者std::cout << '\n'; std::...原创 2019-03-09 15:11:25 · 1531 阅读 · 0 评论