C++部分类,对象总结

友元函数:friend:

1,友元函数:定义在类的外部,但有访问类的所有私有成员,和保护成员,尽管友元函数的原型在类中定义过,但是友元函数并不是成员函数。

2,,友元可以是一个函数,该函数被称为友元函数,友元可以是一个类,该类被称为友元类;在这种情况下,整个类及其所有的成员都是友元。

3,声明一个函数为一个类的友元,需要在类定义中该函数的原型前使用关键字friend.友元函数不属于任何类。


内联函数:inline:

1,内联函数:通常和类一起使用。如果一个函数是内联的,那么在编译时,编译器会把该函数的代码副本放置在每个调用该函数的地方。对内联函数进行任何修改,都需要重新编译函数的所有客户端,因为编译器需要重新更换一次所有的代码,否则将会继续使用旧的函数。

2,如果想把一个函数定义为内联函数,则需要在函数名前面放置关键字inline,在调用函数之前需要对函数进行定义,如果已定义的函数多于一行,编译器会忽略inline限定符。

3,在类定义中的定义的函数都是内联函数,即使没有使用inline说明符;相当于使用inline把一个函数归并到某一个类中。


this:在C++中,每一个对象都能通过this指针来访问自己的地址。this指针是所有的成员啊函数的隐含参数,因此在成员函数内部,它可以用来指向调用对象。友元寒素没有this指针,因为友元不是类的成员,只有成员函数才有this指针。


static 关键字:把类成员定义为静态的,当我们声明类的成员为静态时,意味着无论创建多少个类的对象,静态成员都只有一个副本。

静态成员在类的所有对象中是共享的,如果不存在其他的初始化语句,在创建第一个对象时,所有的静态数据都会被初始化为零,不能把静态成员放置在类的定义中,但是可以在类的外部通过使用范围解析运算符::来重新声明静态变量从而对它进行初始化。


如果把函数成员声明为静态的,就可以把函数与类的任何特定对象独立开来,静态成员函数即使在类对象不存在的情况下也能被调用,静态函数只要使用类名加范围解析运算符::就可以访问。静态成员函数只能访问静态数据成员,不能访问其他静态成员函数和类外部的其他函数。静态成员函数有一个类范围,不能访问类的this指针,可以使用静态成员函数来判断类的某些对象是否已经被创建。


继承:

继承允许我们依据另一个类来定义一个类,这使得创建和维护一个应用程序变得更容易。这样,也达到了重用代码功能和提高执行时间的效果;

当创建了一个类时,不需要重写编写新的数据成员和成员函数,只需要指定新建的类继承了一个已有的类的成员疾苦,这个已有的类叫做基类,新建的类叫做派生类。


基类和派生类:

1,一个类可以派生自多个类,这意味着,它可以从多个基类继承数据和函数,定义一个派生类使用一个类派生列表来指定基类,类派生列表以一个或者多个基类命名。

class derived_class : access-specifier base-class :其中的access-specifier;是publlic ,protected或者private其中的一个,base-class是之前定义过的某个类的名称,如果没有使用访问修饰符,则默认为private.,private,protected 修饰的,派生类不能访问基类中的保护类型和私有类型变量和函数,但是public的可以。

2,访问控制和继承:

派生类可以访问基类中的所有的非私有成员。因此基类成员如果不想让派生类访问,则应在基类中声明为private.

一个派生类继承了所有的基类的方法,但是以下几种不行:

基类的构造函数,析构函数,拷贝构造函数

基类的重载运算符,

基类的友元函数。

3,继承类型:

1)公有继承:当一个类派生字公有基类时,基类的公有成员也是派生类的公有成员,基类的保护成员也是派生类的保护成员,基类的私有成员不能被派生类直接访问,但是可以通过调用基类的公有和保护成员来访问。

2)保护继承:当一个类派生字保护基类时,基类的公有和保护成员将成为派生类的保护成员。

3)私有继承:当一个类派生自私有基类时,基类的公有和保护成员将成为派生类的私有成员。

4,多继承:一个子类可以有多个父类,他继承了多个父类的特性。


4,函数重载

4.1 函数重载

1)  C++允许在同一个作用域中的某个函数和运算符指定的多个定义,分别称为函数重载和运算符重载。

2)重载声明是指一个与之与之前已经在该作用域内声明声明过的函数或方法具有相同名称的声明,但是他们的参数列表和定义(实现)不同。

3)当滴哦啊用一个重载函数或者重载运算符的时,编译器通过把所使用的参数类型和定义中的参数类型进行比较,决定选用最合适的定义,选择最合适的重载函数或重载运算符的过程称为重载决策。函数名相同,返回值类型,参数的类型和个数,顺序不同。

4.2运算符的重载

1)可以重定义或重载大部分的C++内置的运算符,这样就可以使用自定义的类型的运算符。

2)重载的运算符是带有特殊名称的函数,函数名是有关键字operator和其后要重载的运算符符号构成的,与其他函数一样,重载运算符有一个返回类型和一个参数列表。

Box operator+(const Box&);声明加法运算符用于把两个Box对象相加,返回最终的Box对象。大多数的重载运算符可被定义为普通的非成员或者被定义为类成员函数,如果定义上面的函数为类的非成员函数,那么我们需要为诶次从啊U走传递两个参数。

Box operator+(const Box&,const Box&);


5.1:一元运算符只对一个操作数进行操作,一元运算符通常出现它们所操作的对象的左边,但有数也可以作为后缀。

5.2:重载赋值运算符(=),用于创建一个对象,比如拷贝构造函数

5.3,函数调用运算符()可以被重载用于类的对象,当重载()时,创建了一个可以传递任意数目参数的运算符函数。

5.4:下标操作符[]通常用于访问数组元素,重载该运算符用于增强操作C++数组的功能。

5.5:类成员访问运算符:(-->)可以被重载,但较为麻烦,他被定义用于为一个类赋予”指针“行为。运算符-->必须是一个成员函数。如果使用了-->运算符,返回类型必须是指针或者是类的对象。运算符-->通常与指针引用运算符*结合使用,用于实现"智能指针"的功能。这些指针是行为与正常指针相似的对象。唯一不同的是:当通过指针访问对象时,它们会执行其他的任务,比如,当指针销毁是,或者当指针指向另一个对象时,会自动删除对象。

5.6:多态:当类之存在层次结构,并且类之间是通过继承关联时,就会用到多态。C++多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。

在父类中的要实现多态的函数前要添加virtual,这样函数在调用多态的函数时就调用子类的函数了,因为这时编译器看的是指针的内容。会指到子类中去。

5.7虚函数:是在基类中使用关键字virtual声明的函数,在派生类中重新定义的基类中定义的虚函数是,会告诉编译器不要静态链接到该函数。

我们想要在程序中任意点可以根据所调用的对象类型来选择调用的函数,这种操作被称为动态链接,或后期绑定。

5,8纯虚函数:在基类总定义虚函数,在派生类中重新定义该函数更好的适用于对象,但是在基类中又不能对虚函数给出有意义的实现,这个时候就会用到纯虚函数。virtual int area() = 0;告诉编译器,函数没有主体,这样的虚函数就是纯虚函数。


6:数据抽象:

6.1:数据抽象是指:只向外界提供关键信息,并隐藏其后台的实现细节,即只表现必要的信息而不呈现细节。数据抽象是一种依赖于接口和实现分裂的编程设计技术。

6.2:在C++中,使用访问标签来定义类的抽象接口,一个类可以包含另个或者多个访问标签。使用公共标签定义的成员都可以访问该程序的所有部分,一个类型的数据抽象视图是由他的公共成员来定义的。使用私有标签定义的成员无法访问到使用类的的代码,私有部分对使用类型的代码隐藏了实现细节。

6.3:数据抽象的好处:类的内部收到保护,不会因无意的用户级错误导致对象状态的受损。类实现可能随着时间的推移而发生变化,以便应对不断变化的需求,或者应对那些要求不F癌变用户级代码的错误报告。

7,文件和流:

7.1:ofstream:该数据类型表示输出文件流,用于创建文件并向文件写入信息。ifstream:改数据类型表示输入文件流,用于从文件读取信息。fstream:改数据类型通常表示文件流,且同时具有ofstream和istream两种功能,这意味着可以创建文件,向文件中写入信息,从文件读取信息。

7,2:打开文件:iOS::app:追加模式,所有写入都追加到文件末尾;ios::ate:文件打开后定位到那文件末尾。ios::in:打开文件用于读取,ios::out打开文件用于写入;iso::trunc如果该文件已经存在,其内容将在打开之前被截断,即把文件的长度设为0.可以把这几种方式结合使用。

7.3:istream 和ostream都提供了用于重新定位文件指针的成员函数:istream中的seekg("seek get")  和ostream中的seekp("seek out") seekg和seekp的参数通常是一个长整型,第二个参数用于指定查找的方向。查找方向可以是ios::beg(默认的,从流的开始定位),也可以是ios::cur(从流的当前位置开始);也可以是ios::end(从流的末尾开始定位)。文件位置指针是一个整数值,指定了从文件的起始位置到指针所在位置的字节数。

fileobject.seekg(n):定位到从文件的开头的第n个字节。fileObject.seekg(n,ios::cur):把文件的读指针从当前位置向后移动n个字节;fileOBject.seekg(n,ios::end) 把文件的读指针从文件末尾向前移动n个字节;fileObject,seekg(o,ios::end):定位到文件的末尾。


8.1:异常提供了一种转移程序控制权的方式,C++异常处理涉及到的关键字:try,catch,throw.

throw:当问题出现时,程序会抛出一个异常。catch:在您处理问题的地方,通过异常处理程序捕获异常。try:try块中的代码标识将被激活特定的异常。后面通常跟一个或多个catch块。

8.2,抛出异常:在代码块的任何地方抛出异常,throw语句的操作数可以是任意的表达式,表达式的结果的类型决定了抛出的异常的类型。

9,动态内存:C++程序中的内存分为两个部分:栈:在函数内部声明的所有变量都占用栈内存,堆:这是程序中未使用的内存,在程序运行时可用于动态分配内存。

9.1:new:为给定的变量在运行时分配堆内的内存,这会返回所分配的空间地址。

9.2:malloc:函数在C语言中,也在C++中,但是建议不用malloc函数,new比malloc的优势:new不仅分配了内存,而且创建了对象。

9.3:命名空间:作为附加信息来区分不同库中相同名称的函数,类,变量等,使用了命名空间即定义了上下文,本质上:命名空间就是一个范围。


9.4:using namespace:在使用命名空间时就可以不用在前面在前面加上命名空间的名称,这个指令告诉编译器,后续的代码将使用指定的命名空间中的名称。

using指令也可以用来指定命名空间中的特定项目。例如只用std中的cout,则可以:using std::cout.

9.5不连续的命名空间:命名空间可以定义在几个不同的部分中,因此命名空间是由几个单独的定义的部分组成的,一个命名空间的各个组成部分可以分散在多个文件中。所以,如果命名空间中的某个组成部分需要请求定义在另一个文件中的名称,则仍然需要声明该名称。命名空间定义可以是定义一个新的命名空间,也可以是已有的命名空间增加新的元素。

9.6命名空间可以嵌套,通过::运算符来访问嵌套的命名空间中的成员。

namespace namespace_name1 {
   // 代码声明
   namespace namespace_name2 {
      // 代码声明
   }
}
// 访问 namespace_name2 中的成员
using namespace namespace_name1::namespace_name2;

// 访问 namespace:name1 中的成员
using namespace namespace_name1;

10,模板:

10.1:模板是泛型变成的基础,泛型编程即以一种独立于任何特定类型的方式编写代码。

模板是创建泛型类或函数的蓝图或者公式。库容器,比如迭代器和算法,都是泛型编程的例子,他们都是用了模板的概念。每个容器都有一个单一的定义,比如向量,可以使用模板来定义函数和类。

10.2:template <class type>  re-type  func-name(parameter list){}这里的type是函数所使用的数据类型的占位符的名称。这个名称可以在函数定义中使用。

10.3:类模板:template <class type> class class-name{}:其中的type是占位符类型的名称,可以在类被实例化的时候进行指定。


11,预处理器

11.1预处理器是一些指令,指示编译器在实际编译之前所需完成的预处理。

所有预处理指令都是以井号开头,只有空格字符可以出现在预处理指令之前,预处理指令不是C++语句,所以不用分号结尾。

11.2:#和##运算符:预处理运算符在C++和ANSI/ISO  c中都是可用的,#运算符会把要转换的东西转换为引号引起来的字符串。

11.3:用于链接两个令牌,例如:#define CONCAT(x,y)   x##y

11.4:预定义宏:__LINE__这会在程序编译的时候包含当前的行号

__FILE__:这会在程序编译时包含当前文件的文件。__DATE__这回包含一个形式为month/data/year的字符串,它表示把源文件转换为目标代码的日期。

__TIME__:这回包含一个形式为hour:minute:second的字符串,表示编译的时间。其中的下划线是每边都是双线。

12,信号处理

12.1:信号是有操作系统传给进程的中断,会提早终止一个程序,可以通过Ctrl+c中断;

12.2:有些信号可以在程序中被捕获:这些信号定义在C++头文件<csignal>中,

SIGABRT:程序异常终止:入调用abort;

SIGFPE:错误的算术运算,比如除以零或者导致溢出的操作。

SIGILL:检测非法指令

SIGINT:接收到交互注意信号。

SIGSEGV:非法访问内存

SGITERM:发送到程序的终止请求

12.3:C++信号处理库提供了signal函数,用来捕获突发事件。void(*signal(int sig,void(*fun)(int)))(int); 这个函数接收两个参数,第一个参数是整数,代表了信号的编号;第二个参数是一个简单的C++程序,使用signal()函数捕获SIGINT信号,不管捕获什么信号,都必须使用signal函数来注册信号。并将其与信号处理程序相关联。

12.4:raise()函数:使用函数raise()生成信号,该函数带有一个整数信号作为参数。 int raise(signal sig)在这里,sig是要发送的信号的编号,包括上面的几种可以被捕获的信号,

13,:多线程:

13.1:多线程是多任务处理的一种特殊形式,多任务处理允许让电脑同时运行两个或者两个以上的 程序。一般,两种类型的多任务处理:基于进程和基于线程。

基于进程的多任务处理是程序的并发执行;基于线程的多任务处理是同一个程序的片段的并发执行。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

野狼位位

给点辛苦费0.1元

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值