
C++
C++
Jaihk662
这个作者很懒,什么都没留下…
展开
-
运算符重载的非成员函数形式
运算符重载为非成员函数的规则:函数的形参代表依自左至右次序排列的各操作数重载为非成员函数时参数个数 = 原操作数个数(后置++、--除外,它们仍然为了区分前置++、--要强行加个int)至少应该有一个自定义类型的参数(例如"Typ1 operator + (int, double)"非法)如果在运算符的重载函数中需要操作某类对象的私有成员,可以将此函数声明为该类的友元运算符重载为非成员函数的使用方...原创 2018-04-06 01:24:57 · 6131 阅读 · 0 评论 -
类的静态成员
static int 和 int (静态与非静态)的区别:生存期不同,普通变量在离开他的作用域后,存储空间释放,对象消亡用static修饰的变量,生存期为整个程序,即离开它的作用域后,它仍然存在静态变量的初始化只有在第一次使用时才会生效类的静态变量成员:用关键字static声明,要在类外定义和初始化,用(::)来指明所属的类,例如int Point::sum = 0(Point是类名)被该类的所有...原创 2018-03-28 16:58:37 · 344 阅读 · 0 评论 -
私有继承与保护继承(protected 成员)
私有继承(private):继承的访问控制:基类的public和protected成员:都以private身份出现在派生类中基类的private成员:不可直接访问访问权限:派生类中的成员函数:可以直接访问基类中的public和protected成员,但不能直接访问基类的private成员通过派生类的对象:不能直接访问从基类继承的任何成员保护继承(protected):继承的访问控制:基类的publ...原创 2018-04-03 17:25:47 · 1863 阅读 · 1 评论 -
继承基础概念与公有继承
继承与派生概述:被继承的已有类称为基类(或父类),派生出的新类称为派生类(或子类)直接参与派生出某类的基类称为直接基类,基类的基类甚至更高层的基类称为间接基类继承与派生是同一过程从不同的角度看:保持已有类的特性而构造新类的过程称为继承,在已有类的基础上新增自己的特性而产生新类的过程称为派生继承与派生的目的:继承的目的:实现设计与代码的重用。派生的目的:当新的问题出现,原有程序无法解决(或不能完全解...原创 2018-04-03 16:15:20 · 345 阅读 · 0 评论 -
C++字符串输入输出转换
<sstream>输入输出控制类istringstream类:用于执行C++风格的串流的输入操作ostringstream类:用于执行C风格的串流的输出操作strstream类:同时可以支持C风格的串流的输入输出操作字符串输入流(istringstream)用于从字符串读取数据,支持ifstream类的除open、close外的所有操作字符串输出流( ostringstream )用于...原创 2018-04-10 21:17:12 · 454 阅读 · 0 评论 -
C++输出操纵符
插入运算符(<<)为所有标准C++数据类型预先设计的,用于传送字节到一个输出流对象包含头文件"#include<iomanip>"普通操纵符:插入运算符与操纵符一起工作很多操纵符都定义在ios_base类中①dec、oct和hex操纵符,分别代表十进制,八进制和十六进制,使用方法:cout<<oct<<x<<endl;cin>&原创 2018-04-10 19:31:21 · 2075 阅读 · 0 评论 -
new与malloc的不同
new/delete与malloc/free的不同:①new/delete分配内存的位置是自由存储区,malloc/free分配内存的位置是堆自由存储区是C++基于new操作符的一个抽象概念,凡是通过new操作符进行内存申请,该内存即为自由存储区堆是操作系统所维护的一块特殊内存,用于程序的内存动态分配②new内存分配成功返回完整类型指针,而malloc是返回void*类型安全很大情况下等于内存安全...原创 2018-04-15 16:51:24 · 275 阅读 · 0 评论 -
extern关键字
extern关键字:使用:extern int k;作用:告诉编译器:整型变量k是存在的,你需要在其它地方找!当然这个k必须是个全局变量在一个文件中间定义了一个全局变量k,那么在之前如果想使用k就必须extern声明引用另一个文件中的全局变量注意:只能声明,不能进行赋值操作,例如"extern int k = 3"必定非法其它作用:变量可以用extern修饰,函数当然可以,例如"extern vo...原创 2018-04-15 16:21:35 · 284 阅读 · 0 评论 -
标识符的作用域与可见性
作用域是一个标识符在程序正文中有效的区域。作用域分类:函数原型作用域局部作用域(块作用域)类作用域文件作用域(作用域到文件尾结束)命名空间作用域(暂略)作用域的可见性:可见性是从对标识符的引用的角度来谈的概念可见性表示从内层作用域向外层作用域“看”时能看见什么如果标识在某处可见,就可以在该处引用此标识符如果某个标识符在外层中声明,且在内层中没有同一标识符的声明,则该标识符在内层可见对于两个嵌套的作...原创 2018-03-27 16:10:36 · 1300 阅读 · 0 评论 -
友元函数与友元类
类的友元:友元是C++提供的一种破坏数据封装和数据隐藏的机制通过将一个模块声明为另一个模块的友元,一个模块能够引用到另一个模块中本是被隐藏的信息为了确保数据的完整性,及数据封装与隐藏的原则,建议尽量不使用或少使用友元对于友元类,若一个类为另一个类的友元,则此类的所有成员都能访问对方类的私有成员类的友元关系是单向的具体看例子:#include<iostream>#include<...原创 2018-03-28 17:44:10 · 299 阅读 · 0 评论 -
const数据保护
const常量:限定一个变量不允许被改变,产生静态作用使用const在一定程度上可以提高程序的安全性和可靠性对于既需要共享、又需要防止改变的数据应该声明为常类型(用const进行修饰)对于不改变对象状态的成员函数应该声明为常函数。const常量类型:常对象:必须进行初始化,不能被更新,通过常对象只能调用它的常成员函数(const 类型 对象名)常数据成员常成员函数:函数内部不能对任何函数以外定义的...原创 2018-03-28 19:26:45 · 514 阅读 · 0 评论 -
单目运算符重载
前置单目运算符重载规则:设U为前置单目运算符,oprd为类A的对象,则U应被重载为A类的成员函数方式:oprd.operator U()后置单目运算符重载规则:后置单目运算只有两个:"++"和"--"很显然"++"和"--"也可以作为前置单目运算符,这样oprd.operator ++()就会歧义,到底是重置前置的"++"还是后置的"++"呢?解决方法:强行传一个没有意义的int参数只是为原创 2018-04-06 00:53:19 · 1289 阅读 · 0 评论 -
简单运算符重载
运算符重载的规则:运算符重载是对已有的运算符赋予多重含义,使同一个运算符作用于不同类型的数据时导致不同的行为例如string类里面可以通过"str1 += str2"实现两个字符串的拼接C++几乎可以重载全部的运算符,而且只能够重载C++中已经有的以下五个运算符不能重载:"." ".*" "::" "?:" "sizeof"重载之后运算符的优先级和结合性都不会改变运算符重载同等于函数原创 2018-04-05 23:36:22 · 485 阅读 · 0 评论 -
虚基类
前置:同名隐藏与二义性情景解释:暑假结束了,一科作业都没有写的你慌了起来,而班里的大部分同学也都只写了一部分而已,所以不想欠下一点作业的你只好向多个人借作业抄以保证一科都不漏,当然啦,如果当中A同学和B同学都完成了C科作业,你肯定只用抄其中一份就OK了虚基类:需要解决的问题:当派生类从多个基类派生,而这些基类又共同基类,则在访问此共同基类中的成员时,将产生冗余,并有可能因冗余带来不一致性虚基类声明...原创 2018-04-05 20:50:26 · 749 阅读 · 0 评论 -
同名隐藏与二义性
当派生类与基类中有相同成员时:对应的基类同名成员被隐藏①若未特别限定,则通过派生类对象使用的是派生类中的同名成员。②如要通过派生类对象访问基类中被隐藏的同名成员,应使用基类名和作用域操作符(::)来限定。二义性问题:如果从不同基类继承了同名成员,但是在派生类中没有定义同名成员,“派生类对象名或引用名.成员名”或“派生类指针->成员名”访问成员就存在二义性问题解决方法仍然是用类型限定如何解决二...原创 2018-04-05 20:19:23 · 615 阅读 · 0 评论 -
派生类的构造复制与析构
派生类的析构函数析构函数和构造函数一样不被继承,派生类如果需要,要自行声明析构函数声明方法与无继承关系时类的析构函数相同不需要显式地调用基类的析构函数,系统会自动隐式调用先执行派生类析构函数的函数体,再调用基类的析构函数派生类的复制函数一般都要为基类的复制构造函数传递参数。复制构造函数只能接受一个参数,既用来初始化派生类定义的成员,也将被传递给基类的复制构造函数。基类的复制构造函数形参类型是基类对...原创 2018-04-05 19:28:02 · 417 阅读 · 0 评论 -
指针和引用的相同与不同
指针:存储地址的变量,指向内存的一个存储单元,指针是实体引用:变量的别名,和原来的变量本质上是同一个东西相同点:都是地址的概念(一个是某块内存的地址,一个时某块内存的别名)不同点:存在常量指针,不存在常量引用"sizeof(引用)"得到的是所指向对象的大小,而"sizeof(指针)"得到的是指针本身的大小两者的自增运算符意义不同引用在定义时必须初始化,并且不能再被改变指针可以为空指针可以有多级,但...原创 2018-04-05 17:28:14 · 310 阅读 · 0 评论 -
基类与派生类的类型转换
类型转换规则:公有派生类对象可以被当作基类的对象使用,反之则不可派生类的对象可以隐含转换为基类对象派生类的对象可以初始化基类的引用派生类的指针可以隐含转换为基类的指针通过基类对象名,指针只能使用从基类继承的成员#include<iostream>using namespace std;class BaseA{ public: BaseA(int x, int y) {...原创 2018-04-05 14:12:47 · 1851 阅读 · 0 评论 -
#编译预处理
#include包含指令:#include<文件名>:按标准方式搜索,文件位于C++系统目录的include子目录下#include"文件名":首先在当前目录中搜索,若没有再按标准方式搜索#define宏定义指令:→和const很像,但很多时候都被const取代,带参数的宏定义也可以用inline函数取代,所以基本不用#define 标识符 被标识符代表的字符串:其实就是一种替换,例如...原创 2018-03-29 01:17:03 · 432 阅读 · 0 评论 -
UML类图(类关系的表示)
UML的三个基本部分:事物(Things)关系(Relationships)图(Diagrams)类图:例如下面钟表类的表示对象图:UML的几种关系:①依赖关系:(虚线箭头)类A是源,类B是目标,表示类A使用了类B②关联关系:(实线)图中的重数A决定了类B的每个对象与类A的多少个对象发生作用,重数B同理③包含关系→共享聚集(空心菱形)共享聚集:部分可以参加多个整体,例如一个老师在某个学校任职,如果...原创 2018-03-27 14:30:34 · 864 阅读 · 0 评论 -
C++结构体,联合体与枚举类
结构体:C++的结构体可以理解为C语言结构体的升级版,也可以理解为特殊的类,很少用,目的是和C语言保持兼容与类的唯一区别是:类中的成员如果定义在类体的最开头,既没有访问属性(缺省访问),则默认是私有的,而结构体相反默认是公有的联合体:union 联合体名称{ 公有成员 protected: 保护型成员 private: 私有成员}特点:①和C语言中的联合一样,成员共用同一组内存单...原创 2018-03-27 01:45:53 · 488 阅读 · 0 评论 -
类的组合
类的组合(类的成员是另一个类的对象):原则:不仅要负责对本类中的基本类型成员数据初始化,也要对对象成员初始化。例子如下:(代码中有注释)#include<iostream>#include<cmath>using namespace std;class Point{ public: Point(int a = 0, int b = 0) { x = ...原创 2018-03-26 19:20:36 · 415 阅读 · 0 评论 -
虚函数表与动态绑定
(你可能会有一个疑问:编译器是如何实现虚函数的呢?)虚表:每个多态类有一个虚表(virtual table)虚表中有当前类的各个虚函数的入口地址每个对象有一个指向当前类的虚表的指针(虚指针vptr)动态绑定的实现:构造函数中为对象的虚指针赋值通过多态类型的指针或引用调用成员函数时,通过虚指针找到虚表,进而找到所调用的虚函数的入口地址通过该入口地址调用虚函数样例:(图表与程序对应)#include&...原创 2018-04-07 20:50:05 · 630 阅读 · 0 评论 -
虚析构函数
虚析构函数:可通过基类指针删除派生类对象#include<iostream>using namespace std;class Base{ public: Base(int x) { q = new int; *q = x; } virtual ~Base() { printf("Base\n"); //delete q 如果加上这...原创 2018-04-07 19:31:40 · 210 阅读 · 0 评论 -
虚函数与多态
多态性:即让父类的指针有“多种形态”用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数C++支持两种多态性:编译时多态性,运行时多态性编译时多态性:通过重载函数和运算符重载实现运行时多态性:通过虚函数和继承实现虚函数:声明:virtual 函数类型 函数名(形参表)虚函数是实现运行时多态性基础,必须是非静态的成员函数虚函数经过派生之后,就可以实现运行过程中的多态虚函数属于对...原创 2018-04-07 17:46:59 · 432 阅读 · 0 评论 -
浅层复制和深层复制
浅层复制:实现对象间数据元素的一一对应复制深层复制:当被复制的对象数据成员是指针类型时,不是复制该指针成员本身,而是将指针所指对象进行复制对象的浅层复制:class Point{ public: Point(): x(0), y(0) {} Point(int x, int y): x(x), y(y) {} int Getx() { return x; } int Ge...原创 2018-03-30 14:34:55 · 1162 阅读 · 0 评论 -
函数重载
函数重载:C++允许函数在相同的作用域内以相同函数名声明,不过必须满足以下条件:要不形参类型不同,要不形参个数不同,必须满足其一例如你想计算一个数字的平方,当这个数字是整型时返回整型,当这个数字是浮点数时返回浮点数,那么就可以定义两个相同名字的函数:int Square(int x) 和 double Square(double x)这样调用函数Square()时,编译程序将根据实参和形参的类型及...原创 2018-03-24 17:49:18 · 250 阅读 · 0 评论 -
带默认参数值的函数 && 内联函数
内联函数:如果在声明函数时使用关键字inline,编译时会在调用处直接用函数体进行替换,而不是调用函数既然是直接替换,那么里面肯定不能有循环语句,switch语句等注:①内联函数可以避免函数调用,节省参数传递、控制转移等开销②一般编译器自带优化,对于充分简单的函数,编译器可以自动把函数编译成inline的带默认参数值的函数:可以预先设置默认的参数值,调用时如给出实参,则采用实参值,否则采用预先设置...原创 2018-03-24 17:09:24 · 574 阅读 · 0 评论 -
void类型指针 && 指针的各种组合
void类型指针:任何指针都可以赋值给void指针void指针赋值给其它类型指针时都必须经过类型转换void转换前不能参与指针运算,除非转换本质:void指针只知道指向变量/对象的起始地址,却不能知道它们占几个字节指向常量的指针:const int *p1 = &a,不能通过p1改变所指的对象,可以改变指针本身的值指针类型的常量:int *const p2 = &a,可以通过p1改...原创 2018-03-29 22:40:11 · 478 阅读 · 0 评论 -
基于范围的for循环
基于范围的for循环是C++11新特性,可以用它来很方便的遍历整个数组/容器auto自动类型推断:用于从初始化表达式中推断出变量的数据类型,通过auto的自动类型推断,可以大大简化编程工作具体看例子:#include<stdio.h>#include<vector>using namespace std;vector<int> G[15];int a[1...原创 2018-03-29 18:08:29 · 485 阅读 · 0 评论 -
纯虚函数与抽象类
纯虚函数:virtual 函数类型 函数名(形参表) = 0;作用:在许多情况下基类中不能对虚函数给出有意义的实现,而把它声明为纯虚函数,就可以将它的实现留给该基类的派生类去做例如动物作为一个基类可以派生出老虎、狮子等子类,但动物本身生成对象明显不合常理性质:纯虚函数可以让类先具有一个操作名称,而没有操作内容,让派生类在继承时再去具体地给出定义凡是含有纯虚函数的类叫做抽象类(虚基类),如果某个派生...原创 2018-04-07 21:17:08 · 271 阅读 · 0 评论 -
override与final
C++11新特性:在派生类中,重写(override)继承自基类成员函数的实现时,要满足如下条件:基类中,成员函数声明为虚拟的(virtual)基类和派生类中,成员函数的返回类型和异常规格必须兼容基类和派生类中,成员函数名、形参类型、常量属性和引用限定符必须完全相同如此多的限制条件,导致了虚函数重写如上述代码,极容易因为一个不小心而出错解决方案:virtual 函数类型 函数名(形参表) over...原创 2018-04-07 22:19:34 · 494 阅读 · 0 评论 -
复制构造函数与析构函数
复制构造函数:复制构造函数是一种特殊的构造函数,其形参为本类的对象引用,作用是用一个已存在的对象去初始化同类型的新对象如果没有为类声明拷贝初始化构造函数,则编译器自己生成一个隐含的复制构造函数,这个构造函数会用作为初始值的对象的每个数据成员的值,初始化将要建立的对象的对应数据成员,在很多情况下已经很完美了,所以不用自己声明复制构造函数析构函数:相当于是“反·构造函数”,完成对象被删除前的一些清理工...原创 2018-03-26 17:09:04 · 441 阅读 · 1 评论 -
构造函数基本概念
构造函数:作用:在对象被创建时使用特定的值构造对象,将对象初始化为一个特定的初始状态要求:函数名=类型名,不能定义返回值类型,也不能有return语句使用:Clock c(实参1, 实参2,……);如果没有定义构造函数,编译器将在需要时自动生成一个默认构造函数,这个默认构造函数参数列表为空,且初始值可能不确定如果定义了构造函数,编译器就不再隐含生成默认构造函数,如果此时依然希望编译器隐含生成默认构...原创 2018-03-26 14:50:13 · 1310 阅读 · 0 评论 -
C++类模板
类模板的作用:使用类模板使用户可以为类声明一种模式,使得类中的某些数据成员、某些成员函数的参数、某些成员函数的返回值,能取任意类型类模板的使用:template<模板参数表>class 类名 { …… };如果需要在类模板以外定义其成员函数,则要采用以下的形式: template<模板参数表>类型名 类名<模板参数标识符列表>::函数名(参数表)具体见程...原创 2018-04-08 20:11:03 · 213 阅读 · 0 评论 -
C++函数模板
函数模板作用:同一功能的函数可能会因为类型问题要写两个甚至更多,比如取绝对值,对整数取绝对值和对浮点数取绝对值是一样的,然而都要处理的话必须写两个函数,这样非常麻烦,使用函数模板就可以解决这个问题(写一个通用类型函数)函数模板定义:函数模板定义形式:template<模板参数表>,一般使用类型参数class或typename标识符例如template<class T>、te...原创 2018-04-08 19:33:53 · 361 阅读 · 0 评论 -
C++this指针
this指针:C++中每一个对象都有一个this指针访问自己,它也是所有成员的隐含参数一个对象的this指针并不是对象本身的一部分,不会影响sizeof(对象)的结果this作用域是在类内部,当在类的非静态成员函数中访问类的非静态成员的时候,编译器会自动将对象本身的地址作为一个隐含参数传递给函数它作为非静态成员函数的隐含形参,对各成员的访问均通过this进行任何对类成员的直接访问都被看成this的...原创 2018-03-31 22:21:40 · 240 阅读 · 0 评论 -
运算优先级、类型转换
运算符优先级:混合运算时数据类型的转换:一些二元运算符(算术运算符、关系运算符、逻辑运算符、位运算符和赋值运算符)要求两个操作数的类型一致,在算术运算和关系运算中如果参与运算的操作数类型不一致,编译系统会自动对数据进行转换(即隐含转换),基本原则是将低类型数据转换为高类型数据混合运算时数据类型的转换——显式转换:显式类型转换的作用是将表达式的结果类型转换为类型说明符所指定的类型语法形式:①类型说明...原创 2018-03-21 18:47:55 · 529 阅读 · 0 评论 -
static_cast与dynamic_cast类型转换
static_cast:类型转换:static_cast<type>(exdivssion),例k = static_cast<double>(1234)①把空指针转换成目标类型的空指针②把任何类型的表达式转换成void类型③用于基本数据类型之间的转换④用于类层次结构中基类和子类之间指针或引用的转换→上行转换,即把子类的指针或引用转换成基类表示(安全)→下行转换,即把基类指...原创 2018-04-07 23:48:18 · 458 阅读 · 0 评论 -
对象数组
对象数组初始化:数组中每一个元素对象被创建时,系统都会调用类构造函数初始化该对象可以通过初始化列表赋值,例:Point a[10] = {Point(1,2), Point(3,4)};如果没有为数组元素指定显式初始值,数组元素便会调用默认构造函数数组中每一个对象被删除时系统都要调用一次析构函数例子:#include<stdio.h>#include<iostream>...原创 2018-03-29 17:40:16 · 489 阅读 · 0 评论