随笔分类 - C++ 学习笔记
1
摘要:Vector List构造函数可以初始化顺序容器的大小(size t) , t 可以指定顺序容器的capacity。第二个参数可以指定容器的默认值。reserve是容器预留空间,但在空间内不真正创建元素对象,所以在没有添加新的对象之前,不能引用容器内的元素。加入新的元素时,要调用push_back()/insert()函数。resize是改变容器的大小,且在创建对象,因此,调用这个函数之后,就可以引用容器内的对象了,因此当加入新的元素时,用operator[]操作符,或者用迭代器来引用元素对象。此时再调用push_back()函数,是加在这个新的空间后面的。两个函数的参数形式也有区别的,res
阅读全文
摘要:C++编程语言中有一种叫做new的二维数组,它的应用方式比较灵活,可以有多种方法来帮助我们实现一些特定功能。在这里我们将会总结几种C++二维数组new的应用方式,来进行逐一的点评。C++二维数组new应用方式一:A (*ga)[n] = new A[m][n]; ... delete []ga; 缺点:n必须是已知优点:调用直观,连续储存,程序简洁(经过测试,析构函数能正确调用)C++二维数组new应用方式二:A** ga = new A*[m]; for(int i = 0; i ga; ga.resize(m); //这三行可用可不用 for(int i = 1; i < n; i+
阅读全文
摘要:makefile 及gcc参数makefile可以定义变量在makefile前几行变量名=变量值makefile 命令一定是以tab开头的,否则会出现missing separator错误makefile可以自动生成一系列某种类型的文件,用法 %.后缀名 : %.传入文件后缀名执行方法如,生成.obj文件,文件名用 $*.xxx 代替%.obj : %.cgcc -Ixxx-o [输出路径变量]$*.obj[输入路径变量]$*.c [输入路径变量]为makefile定义的变量,使用 $(变量名),可选具体例子:%.obj : %.asm Makefile$(NASK) $*.asm $(RE.
阅读全文
摘要:strcpy慎用因为如果源字符串和目的字符串分配在连续的空间,而且空间大小仅仅是足够容纳最初的字符串,那么strcpy在复制是只考虑源字符串的\0,不会考虑空间大小,那么就很容易使得访问目的地址越界,而且如果目的字符串存放的空间在源字符串的前面,而且比源字符串短,那么,复制将会导致源字符串前面的字符丢失123\0123456789\0目的 源字符串拷贝后123\0123456789\0目的 源字符串123456789\0789\0目的 源所以调用strcpy的字符串目的地和源都必须有足够的预留空间
阅读全文
摘要:main函数执行前后执行其他语句main 运行前static 类型的对象会在main函数之前初始化,所以在某个类的构造方法执行的代码是在main函数前执行,可以通过这种方式实现在main函数之前执行代码main跳出后main()函数执行完毕后会倒着顺序执行atexit函数,一个程序最多可以注册32个atexit函数先注册后执行void exe07_part1(){ cout<<"part1"<<endl;}void exe07_part2(){ cout<<"part2"<<endl;}void exe07
阅读全文
摘要:stl提供了三个最基本的容器:vector,list,deque。vector和built-in数组类似,它拥有一段连续的内存空间,并且起始地址不变,因此它能非常好的支持随即存取,即[]操作符,但由于它的内存空间是连续的,所以在中间进行插入和删除会造成内存块的拷贝,另外,当该数组后的内存空间不够时,需要重新申请一块足够大的内存并进行内存的拷贝。这些都大大影响了vector的效率。list就是数据结构中的双向链表(根据sgi stl源代码),因此它的内存空间可以是不连续的,通过指针来进行数据的访问,这个特点使得它的随即存取变的非常没有效率,因此它没有提供[]操作符的重载。但由于链表的特点,它可以
阅读全文
摘要:RTTI(Run-Time Type Identification,通过运行时类型识别)程序能够使用基类的指针或引用来检查这些指针或引用所指的对象的实际派生类型。RTTI提供了以下两个非常有用的操作符:(1)typeid操作符,返回指针和引用所指的实际类型。(2)dynamic_cast操作符,将基类类型的指针或引用安全地转换为派生类型的指针或引用。typeid操纵符会返回一个type_info类,这个类有一个成员函数是name()得到类型名,type_info类构造方法私有,只能由typeid产生,type_info重载了== 和!= ,隐藏了赋值运算符=,所以可以用来比较两个变量的类型是否
阅读全文
摘要://HeapOnly.cpp #include using namespace std;只能在堆上分配空间:我们可将类的析构函数用private来修饰,也就是把析构函数私有化,因为自动变量与静态变量的对象都在释放空间的时候都需要访问析构函数。若析构函数私有,外面就不能调用,这时候会产生编译错误,这样就达到了只能在堆上分配空间了。但是,把析构函数私有化,那么我们就不能调用delete了, 因为它也需要访问析构函数。这就要求我们自己去提供回收内存空间的函数,以防内存泄漏。 class HeapOnly { public: HeapOnly() { cout destroy(); // HeapO.
阅读全文
摘要:C 里面static 声明的变量只对本源文件可见变量存储在静态存储区,初始化为0只初始化一次,比如在函数体里面声明的值编译出的程序执行时不会重复声明
阅读全文
摘要:虚拟继承虚继承会在派生类加多一个指向基类的指针(除非基类没有数据成员,这样就没有必要用一个指针去指向基类了),如果基类和派生类都有虚函数,同用,如果基类A,B有两个,而且两个基类还有base基类,那么虚继承后也有一个指针指向base(base要有数据才行)总结:无论继承了多少类,一个类只有最多一个虚函数表指针;无论继承多么乱,某一个基类最多只有一个指针指向(特殊是基类没有数据成员,就没必要为其分配一个指针)
阅读全文
摘要:虚函数和纯虚函数有以下所示方面的区别。(1)类里如果声明了虚函数,这个函数是实现的,哪怕是空实现,它的作用就是为了能让这个函数在它的子类里面可以被覆盖,这样的话,这样编译器就可以使用后期绑定来达到多态了。纯虚函数只是一个接口,是个函数的声明而已,它要留到子类里去实现。(2)虚函数在子类里面也可以不重载的;但纯虚函数必须在子类去实现,这就像Java的接口一样。通常把很多函数加上virtual,是一个好的习惯,虽然牺牲了一些性能,但是增加了面向对象的多态性,因为很难预料到父类里面的这个函数不在子类里面不去修改它的实现。(3)虚函数的类用于“实作继承”,继承接口的同时也继承了父类的实现。当然大家也可
阅读全文
摘要:标准C++中有没有接口和纯抽象类的概念?下面是C++的创造者的回答,供你参考Bjarne Stroustrup:我在对人们解释这个问题的过程中遇到了很多问题,而且我也一直不能理解为什么让人们理解这个问题是如此困难。自C++出现那天起,就存在着包含数据成员的类和不包含数据成员的类。在过去,人们强调利用一个最基础的设施以及该设施内部的东西来构造软件系统,而那个“最基本的设施”通常就是抽象基类。从80年代中叶到80年代末,那些仅由虚拟函数组合而成的类通常都被称为ABCs(Abstract Base Classes 抽象基类)。1987年,我在C++中加入了纯虚函数的概念,一个纯虚函数必须被其派生类重
阅读全文
摘要:C++构造函数调用自身的另一个构造函数在Java中,可以通过this(参数)或者类名(参数) 调用自身的另一个构造方法,但在C++中,直接调用 类名(参数)是不行的,因为这样C++会从新分配内存,并且在当前构造方法结束时会调用析构函数,导致对象构造不成功,导致不能像Java那样初始化对象。C++正确调用方法是new(this)构造方法(参数)析构函数析构函数是在包含其对象的右括号结束地方被调用int main(){ { A a;}//a.~A();将在此处被调用}
阅读全文
摘要:一 抽象类和接口抽象类:抽象类是特殊的类,只是不能被实例化(将定义了纯虚函数的类称为抽象类);除此以外,具有类的其他特性;重要的是抽象类可以包括抽象方法,这是普通类所不能的,但同时也能包括普通的方法。抽象方法只能声明于抽象类中,且不包含任何实现,派生类必须覆盖它们。另外,抽象类可以派生自一个抽象类,可以覆盖基类的抽象方法也可以不覆盖,如果不覆盖,则其派生类必须覆盖它们。虽然不能定义抽象类的实例,但是可以定义它的指针,这正是用抽象类实现接口的重点所在。接口:接口是一个概念。它在C++中用抽象类来实现,在C#和Java中用interface来实现。接口是引用类型的,类似于类,和抽象类的相似之处有三
阅读全文
摘要:枚举类型我们在写程序的时候常常需要定义一组与对象相关的属性例如一个文件可能会以三种状态输入输出和追加之一被打开典型情况下我们通过把每个属性和一个唯一的const 值相关联来记录这些状态值因此我们可能会这样写const int input = 1;const int output = 2;const int append = 3;并按如下方式使用这些常量bool open_file( string file_name, int open_mode);// ...open_file( "Phoenix_and_the_Crane", append );尽管这样做也能奏效但是它有
阅读全文
摘要:C++数组1、被显式初始化的数组不需要指定维数值编译器会根据列出来的元素的个数来确定数组的维数// 维数为3 的数组int ia[] = { 0, 1, 2 };2、指定维数的数字如果显式初始化数字,初始化队列不能超过维数大小,如果小于维数大小,用0填充3、字符数组 ,用{}和""方式初始化的数字长度不一样,""初始化的数组维数多一,用来存放04、一个数组不能被另外一个数组初始化也不能被赋值给另外一个数组而且C++不允许声明一个引用数组(即由引用组成的数组),要把一个数组拷贝到另一个中去必须按顺序拷贝每个元素// ok: 类型为int*的指针的数组int
阅读全文
摘要:通过类句柄减少编译次数当一个项目的类的头文件包含了另一个类,但是如果修改了另一个类,那么所以包含这个类的所有类都要重新编译,这样导致项目编译次数增多,浪费资源。通过类句柄可以解决这个问题。例子://handle.hclass handle{class cheshire; //这就是类句柄,声明了handle类有一个cheshire的类,但没有定义cheshire *c; //使用cheshire类声明一个变量public:void init();void read();}//另外一个文件:handle.cppclass handle::cheshire{//数据成员//函数成员}void ha
阅读全文
摘要:1 C的声明与定义声明是告诉编译器存在某一个函数或者变量定义是编译器为某一名称的函数或变量分配存储地址定义可以包括声明声明常常使用extern关键字,不带函数体的函数自动作为声明,可以理解为自动加上extern关键字。C++函数原型: 返回类型 函数名(,...);C++中函数声明至少是一个函数原型,函数定义时必须给出各个参数名C 和C++ 都允许对函数重复声明2 C++中,struct里面可以声明,定义函数,所声明的函数成为成员函数,成员函数的定义可以在结构体之外,定义:返回类型 结构体名称::函数名(参数表){函数体};::为C++的新定义的运算符,成为作用域限定符3 C++中如果一个结构
阅读全文
摘要:重载与缺省参数C++全局函数与类成员函数在编译器编译时以类名+函数名确定内部函数名C++函数重载编译器一般以参数产生内部函数名C++不能以返回值作为重载的原因:很多情况下函数调用者调用函数并不需要返回值,如果存在一个void f(); int f(); 当调用f();时编译器不能确定究竟是调用哪个函数。C++安全连接//:def.cppvoid f(int){} //f(int)定义//:use.cppvoid f(char); //f(char)声明int main(){ f(1); return 0;}以上代码在C中可以编译成功,但在C++中不行,由于use.cpp声明了f(cha...
阅读全文
摘要:隐藏的实现private,protected,public三个关键字C与C++的区别:struct 和class关键字,不再权限关键字下的成员,struct默认为公有(public),class默认为私有(private)友元定义函数或者类为当前类的友元则友元函数或类对当前类具有所有的访问权限,友元只能在某个类里面定义,因为只有类有权限的意义void global_fun();class b{public: void b_member_fun(); void b_member_fun2();};class c{ public: void c_member_fun();}class a{...
阅读全文
1
浙公网安备 33010602011771号